https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122878

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |redi at gcc dot gnu.org
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |ASSIGNED
   Target Milestone|---                         |16.0
   Last reconfirmed|                            |2025-11-26

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This patch fixes it:

--- a/libstdc++-v3/src/c++20/atomic.cc
+++ b/libstdc++-v3/src/c++20/atomic.cc
@@ -669,11 +669,13 @@ __wait_until_impl([[maybe_unused]] const void* __addr,
__wait_args_base& __args,

   if (__args & __wait_flags::__do_spin)
     {
-      auto __res = __detail::__spin_until_impl(__wait_addr, __args, __atime);
+      auto __res = __detail::__spin_impl(__wait_addr, __args);
       if (!__res._M_timeout)
        return __res;
       if (__args & __wait_flags::__spin_only)
        return __res;
+      if (__wait_clock_t::now() >= __atime)
+       return __res;
     }

 #ifdef _GLIBCXX_HAVE_PLATFORM_WAIT


The __spin_until_impl function should stop spinning after some finite duration,
but instead it just spins (and sleeps) until the deadline is passed. That means
there's no use for the futex wait, because we always just spin until the
timeout.

Additionally, there was no check after __spin_until_loop to see whether the
deadline is passed, so we were proceeding to the futex wait anyway, when we
should have returned with a timeout.

With the patch above the benchmark gives:

BM_counting_sema        2770 ns         2767 ns       250728

Reply via email to