[libc-commits] [libc] [libc] avoid cmpxchg on the fastpath of callonce (PR #91748)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Fri May 10 07:23:54 PDT 2024
https://github.com/SchrodingerZhu created https://github.com/llvm/llvm-project/pull/91748
Avoid `cmpxchg` operation if the function has already been called.
The destination operand of `cmpxchg` may receive a write cycle without regard to the result of the comparison
>From 8c62ba1555671a3c786fb3d8232623b99d486be1 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Fri, 10 May 2024 10:23:02 -0400
Subject: [PATCH] [libc] avoid cmpxchg on the fastpath of callonce
---
libc/src/__support/threads/linux/callonce.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/libc/src/__support/threads/linux/callonce.cpp b/libc/src/__support/threads/linux/callonce.cpp
index 1c29db5f5c1a1..b48a514a44875 100644
--- a/libc/src/__support/threads/linux/callonce.cpp
+++ b/libc/src/__support/threads/linux/callonce.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/__support/threads/callonce.h"
+#include "src/__support/macros/optimization.h"
#include "src/__support/threads/linux/futex_utils.h"
namespace LIBC_NAMESPACE {
@@ -21,6 +22,12 @@ int callonce(CallOnceFlag *flag, CallOnceCallback *func) {
FutexWordType not_called = NOT_CALLED;
+ // Avoid cmpxchg operation if the function has already been called.
+ // The destination operand of cmpxchg may receive a write cycle without
+ // regard to the result of the comparison
+ if (LIBC_LIKELY(futex_word->load(cpp::MemoryOrder::RELAXED) == FINISH))
+ return 0;
+
// The call_once call can return only after the called function |func|
// returns. So, we use futexes to synchronize calls with the same flag value.
if (futex_word->compare_exchange_strong(not_called, START)) {
More information about the libc-commits
mailing list