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

            Bug ID: 98033
           Summary: ABA problem in atomic wait
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

In __atomic_wait in include/bits/atomic_wait.h we have:

      while (!__pred())
        {
          if constexpr (__platform_wait_uses_type<_Tp>)
            {
              __platform_wait(__addr, __old);
            }

If the predicate is initially false (i.e. *addr == old) we enter the loop. If
the value changes before calling __platform_wait then that will return
immediately. If it then changes back to the old value the predicate will be
false again and we will re-enter the loop. This time __platform_wait will block
waiting for the value to change.

The standard says we're allowed to miss such transient values, and so the code
above is conforming. But I think we can make it work on linux for the
std::atomic_signed_lock_free type at least (which isn't defined, but should be
atomic<int>).

If __platform_wait returned a boolean indicating whether the not-equal
condition was met (either because it was already true, the EAGAIN case, or
because the futex wait got woken up) then the caller could check that and not
re-check the predicate.

Reply via email to