-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[libc++] fix atomic::wait memory order #146267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-libcxx Author: Hui (huixie90) ChangesFull diff: https://github.com/llvm/llvm-project/pull/146267.diff 1 Files Affected:
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
index c1af8d6f95aae..585fd1f538e46 100644
--- a/libcxx/src/atomic.cpp
+++ b/libcxx/src/atomic.cpp
@@ -151,8 +151,9 @@ __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);
// We sleep as long as the monitored value hasn't changed.
+ __cxx_atomic_thread_fence(memory_order_seq_cst);
__libcpp_platform_wait_on_address(__platform_state, __old_value);
__cxx_atomic_fetch_sub(__contention_state, __cxx_contention_t(1), memory_order_release);
}
@@ -163,7 +164,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,
|
Thanks for taking this issue on! This looks like a correct implementation of "Option 1a" from the original issue I raised. That's been verified by three separate people using Herd, Dartagnan and GenMC respectively, so we're relatively sure it's doing the right thing at this point! |
@@ -163,7 +164,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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with LLVM coding conventions, but would it be worth adding a note here about the fact that there are no platform guarantees of a memory barrier in the platform wait implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but +1 about adding a comment.
Fixes #109290
See the GH issue for the details. In conclusion, we have two issues in the
atomic<T>::wait
whenT
does not match ourcontention_t
:futex_wait
/__ulock_wait
) has seq_cst barrier internally but there is no such guarantee