libstdc++: Fix handling of futex wake [PR 97936]

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.
This commit is contained in:
Jonathan Wakely 2020-11-25 10:26:09 +00:00
parent a7285c8659
commit ad9cbcee54
3 changed files with 2 additions and 4 deletions

View file

@ -100,9 +100,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
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);
}
}

View file

@ -19,7 +19,6 @@
// { dg-do run { target c++2a } }
// { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } }
// { dg-skip-if "broken" { *-*-* } }
#include <latch>
#include <atomic>

View file

@ -19,7 +19,6 @@
// { dg-do run { target c++2a } }
// { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } }
// { dg-skip-if "broken" { *-*-* } }
#include <semaphore>
#include <chrono>