summaryrefslogtreecommitdiff
path: root/libc/src/__support/threads/linux/callonce.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src/__support/threads/linux/callonce.cpp')
-rw-r--r--libc/src/__support/threads/linux/callonce.cpp19
1 files changed, 4 insertions, 15 deletions
diff --git a/libc/src/__support/threads/linux/callonce.cpp b/libc/src/__support/threads/linux/callonce.cpp
index b48a514a4487..24d376f447fb 100644
--- a/libc/src/__support/threads/linux/callonce.cpp
+++ b/libc/src/__support/threads/linux/callonce.cpp
@@ -7,27 +7,16 @@
//===----------------------------------------------------------------------===//
#include "src/__support/threads/callonce.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/threads/linux/callonce.h"
#include "src/__support/threads/linux/futex_utils.h"
namespace LIBC_NAMESPACE {
-
-static constexpr FutexWordType NOT_CALLED = 0x0;
-static constexpr FutexWordType START = 0x11;
-static constexpr FutexWordType WAITING = 0x22;
-static constexpr FutexWordType FINISH = 0x33;
-
-int callonce(CallOnceFlag *flag, CallOnceCallback *func) {
+namespace callonce_impl {
+int callonce_slowpath(CallOnceFlag *flag, CallOnceCallback *func) {
auto *futex_word = reinterpret_cast<Futex *>(flag);
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)) {
@@ -46,5 +35,5 @@ int callonce(CallOnceFlag *flag, CallOnceCallback *func) {
return 0;
}
-
+} // namespace callonce_impl
} // namespace LIBC_NAMESPACE