The __platform_wait function is supposed to wait until *addr != old.
The futex syscall checks the initial value and returns EAGAIN if *addr
!= old is already true, which should cause __platform_wait to return.
Instead it loops and keeps doing a futex wait, which keeps returning
EAGAIN.
libstdc++-v3/ChangeLog:
PR libstdc++/97936
* include/bits/atomic_wait.h (__platform_wait): Return if futex
sets EAGAIN.
* testsuite/30_threads/latch/3.cc: Re-enable test.
* testsuite/30_threads/semaphore/try_acquire_until.cc: Likewise.
auto __e = syscall (SYS_futex, static_cast<const void*>(__addr),
static_cast<int>(__futex_wait_flags::__wait_private),
__val, nullptr);
- if (!__e)
+ if (!__e || EAGAIN)
break;
- else if (!(errno == EINTR || errno == EAGAIN))
+ else if (errno != EINTR)
__throw_system_error(__e);
}
}
// { dg-do run { target c++2a } }
// { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } }
-// { dg-skip-if "broken" { *-*-* } }
#include <latch>
#include <atomic>
// { dg-do run { target c++2a } }
// { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } }
-// { dg-skip-if "broken" { *-*-* } }
#include <semaphore>
#include <chrono>