From ad9cbcee543ecccd79fa49dafcd925532d2ce210 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 25 Nov 2020 10:26:09 +0000 Subject: [PATCH] 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. --- libstdc++-v3/include/bits/atomic_wait.h | 4 ++-- libstdc++-v3/testsuite/30_threads/latch/3.cc | 1 - .../testsuite/30_threads/semaphore/try_acquire_until.cc | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h index cd756f68de6..fdf7c4586f2 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -100,9 +100,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __e = syscall (SYS_futex, static_cast(__addr), static_cast(__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); } } diff --git a/libstdc++-v3/testsuite/30_threads/latch/3.cc b/libstdc++-v3/testsuite/30_threads/latch/3.cc index 6304135a877..70f2d183e87 100644 --- a/libstdc++-v3/testsuite/30_threads/latch/3.cc +++ b/libstdc++-v3/testsuite/30_threads/latch/3.cc @@ -19,7 +19,6 @@ // { dg-do run { target c++2a } } // { dg-require-gthreads "" } // { dg-additional-options "-pthread" { target pthread } } -// { dg-skip-if "broken" { *-*-* } } #include #include diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc index 5e1141425f7..58f68ce9e1e 100644 --- a/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc +++ b/libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc @@ -19,7 +19,6 @@ // { dg-do run { target c++2a } } // { dg-require-gthreads "" } // { dg-additional-options "-pthread" { target pthread } } -// { dg-skip-if "broken" { *-*-* } } #include #include -- 2.30.2