aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src
diff options
context:
space:
mode:
authorHui <hui.xie1990@gmail.com>2025-07-06 09:23:19 +0100
committerGitHub <noreply@github.com>2025-07-06 09:23:19 +0100
commitc358979d7f45fc7624abc2f14e6f36f25ac9acc0 (patch)
treee8c9559a3cc3e6a398d047fbf5a9e6ff1739eab3 /libcxx/src
parentba7d78ac4597c99e1815646d711cf736ead4f54a (diff)
downloadllvm-c358979d7f45fc7624abc2f14e6f36f25ac9acc0.zip
llvm-c358979d7f45fc7624abc2f14e6f36f25ac9acc0.tar.gz
llvm-c358979d7f45fc7624abc2f14e6f36f25ac9acc0.tar.bz2
[libc++] fix atomic::wait memory order (#146267)
Fixes #109290 See the GH issue for the details. In conclusion, we have two issues in the `atomic<T>::wait` when `T` does not match our `contention_t`: - We don't have a total single order which can leads to missed notification based on the Herd7 simulation on relaxed architectural like PowerPC - We assumed the platform wait (`futex_wait`/`__ulock_wait`) has seq_cst barrier internally but there is no such guarantee
Diffstat (limited to 'libcxx/src')
-rw-r--r--libcxx/src/atomic.cpp7
1 files changed, 5 insertions, 2 deletions
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index c1af8d6..903084d 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -151,7 +151,10 @@ __libcpp_contention_monitor_for_wait(__cxx_atomic_contention_t volatile* /*__con
static void __libcpp_contention_wait(__cxx_atomic_contention_t volatile* __contention_state,
__cxx_atomic_contention_t const volatile* __platform_state,
__cxx_contention_t __old_value) {
- __cxx_atomic_fetch_add(__contention_state, __cxx_contention_t(1), memory_order_seq_cst);
+ __cxx_atomic_fetch_add(__contention_state, __cxx_contention_t(1), memory_order_relaxed);
+ // https://github.com/llvm/llvm-project/issues/109290
+ // There are no platform guarantees of a memory barrier in the platform wait implementation
+ __cxx_atomic_thread_fence(memory_order_seq_cst);
// We sleep as long as the monitored value hasn't changed.
__libcpp_platform_wait_on_address(__platform_state, __old_value);
__cxx_atomic_fetch_sub(__contention_state, __cxx_contention_t(1), memory_order_release);
@@ -163,7 +166,7 @@ static void __libcpp_contention_wait(__cxx_atomic_contention_t volatile* __conte
static void __libcpp_atomic_notify(void const volatile* __location) {
auto const __entry = __libcpp_contention_state(__location);
// The value sequence laundering happens on the next line below.
- __cxx_atomic_fetch_add(&__entry->__platform_state, __cxx_contention_t(1), memory_order_release);
+ __cxx_atomic_fetch_add(&__entry->__platform_state, __cxx_contention_t(1), memory_order_seq_cst);
__libcpp_contention_notify(
&__entry->__contention_state,
&__entry->__platform_state,