File tree Expand file tree Collapse file tree 3 files changed +26
-43
lines changed
libc/src/__support/threads/linux Expand file tree Collapse file tree 3 files changed +26
-43
lines changed Original file line number Diff line number Diff line change @@ -97,10 +97,8 @@ add_object_library(
9797 # value other than 0 is dangerous. We know.
9898)
9999
100- add_object_library (
100+ add_header_library (
101101 callonce
102- SRCS
103- callonce.cpp
104102 HDRS
105103 ../callonce.h
106104 callonce.h
Load Diff This file was deleted.
Original file line number Diff line number Diff line change @@ -26,6 +26,31 @@ static constexpr FutexWordType FINISH = 0x33;
2626LIBC_INLINE bool callonce_fastpath (CallOnceFlag *flag) {
2727 return flag->load (cpp::MemoryOrder::RELAXED) == FINISH;
2828}
29+
30+ [[gnu::noinline]]
31+ LIBC_INLINE int callonce_slowpath (CallOnceFlag *flag, void (*func)(void )) {
32+ auto *futex_word = reinterpret_cast <Futex *>(flag);
33+
34+ FutexWordType not_called = NOT_CALLED;
35+
36+ // The call_once call can return only after the called function |func|
37+ // returns. So, we use futexes to synchronize calls with the same flag value.
38+ if (futex_word->compare_exchange_strong (not_called, START)) {
39+ func ();
40+ auto status = futex_word->exchange (FINISH);
41+ if (status == WAITING)
42+ futex_word->notify_all ();
43+ return 0 ;
44+ }
45+
46+ FutexWordType status = START;
47+ if (futex_word->compare_exchange_strong (status, WAITING) ||
48+ status == WAITING) {
49+ futex_word->wait (WAITING);
50+ }
51+
52+ return 0 ;
53+ }
2954} // namespace callonce_impl
3055
3156} // namespace LIBC_NAMESPACE_DECL
You can’t perform that action at this time.
0 commit comments