[libcxx-commits] [libcxx] c358979 - [libc++] fix atomic::wait memory order (#146267)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 6 01:23:22 PDT 2025


Author: Hui
Date: 2025-07-06T09:23:19+01:00
New Revision: c358979d7f45fc7624abc2f14e6f36f25ac9acc0

URL: https://github.com/llvm/llvm-project/commit/c358979d7f45fc7624abc2f14e6f36f25ac9acc0
DIFF: https://github.com/llvm/llvm-project/commit/c358979d7f45fc7624abc2f14e6f36f25ac9acc0.diff

LOG: [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

Added: 
    

Modified: 
    libcxx/src/atomic.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index c1af8d6f95aae..903084da053a1 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,


        


More information about the libcxx-commits mailing list