https://gcc.gnu.org/g:ba1ad0ec6fe6b8ee3e6682f266f7a336a15f7965

commit r16-1248-gba1ad0ec6fe6b8ee3e6682f266f7a336a15f7965
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Jun 4 16:58:45 2025 +0100

    libstdc++: Add assertions to atomic waiting functions that need platform 
wait
    
    These overloads should never be used for proxy waits, so add assertions
    to ensure that they aren't used accidentally.
    
    The reason they can't be used is that they don't call
    __args._M_setup_wait to obtain a __wait_state pointer. Even if that was
    changed, they would wait on a proxy wait which is potentially used by
    many other threads waiting on other addresses, meaning spurious wake ups
    are likely. In order to make the functions correct they would need to
    perform additional loads and comparisons of the atomic variable before
    calling __wait_impl or __wait_until_impl, which would make these
    functions no faster than the general purpose overloads that take an
    accessor function and predicate. That would be possible, and I think
    they would then work for proxy waits, but doesn't seem necessary at this
    time.
    
    In order to preseve the property that these functions are more
    lightweight and efficient than the general ones, they should not be used
    for proxy waits.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/atomic_timed_wait.h (__atomic_wait_address_until_v):
            Add assertion to prevent use with proxy waits.
            (__atomic_wait_address_for_v): Likewise.
            * include/bits/atomic_wait.h (__atomic_wait_address_v):
            Likewise.

Diff:
---
 libstdc++-v3/include/bits/atomic_timed_wait.h | 6 ++++++
 libstdc++-v3/include/bits/atomic_wait.h       | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h 
b/libstdc++-v3/include/bits/atomic_timed_wait.h
index bd2e6bf61ecf..30f7ff616840 100644
--- a/libstdc++-v3/include/bits/atomic_timed_wait.h
+++ b/libstdc++-v3/include/bits/atomic_timed_wait.h
@@ -156,6 +156,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                  const chrono::time_point<_Clock, _Dur>& 
__atime,
                                  bool __bare_wait = false) noexcept
     {
+#ifndef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT
+      __glibcxx_assert(false); // This function can't be used for proxy wait.
+#endif
       __detail::__wait_args __args{ __addr, __old, __order, __bare_wait };
       auto __res = __detail::__wait_until(__addr, __args, __atime);
       return !__res._M_timeout; // C++26 will also return last observed __val
@@ -205,6 +208,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                const chrono::duration<_Rep, _Period>& __rtime,
                                bool __bare_wait = false) noexcept
     {
+#ifndef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT
+      __glibcxx_assert(false); // This function can't be used for proxy wait.
+#endif
       __detail::__wait_args __args{ __addr, __old, __order, __bare_wait };
       auto __res = __detail::__wait_for(__addr, __args, __rtime);
       return !__res._M_timeout; // C++26 will also return last observed __val
diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h
index 9ae11191d9ab..95151479c120 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -255,6 +255,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                          __detail::__platform_wait_t __old,
                          int __order, bool __bare_wait = false)
   {
+#ifndef _GLIBCXX_HAVE_PLATFORM_WAIT
+    __glibcxx_assert(false); // This function can't be used for proxy wait.
+#endif
     __detail::__wait_args __args{ __addr, __old, __order, __bare_wait };
     // C++26 will not ignore the return value here
     __detail::__wait_impl(__addr, __args);

Reply via email to