libstdc++: Fix handling of futex wake [PR 97936]
authorJonathan Wakely <jwakely@redhat.com>
Wed, 25 Nov 2020 10:26:09 +0000 (10:26 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 25 Nov 2020 10:31:55 +0000 (10:31 +0000)
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
libstdc++-v3/testsuite/30_threads/latch/3.cc
libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc

index cd756f68de6db5cd567ff2d4a97d4767fbaf75a0..fdf7c4586f22ec06c610548cf58cba7b88e091c3 100644 (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);
          }
       }
index 6304135a877c352e961b027bb2266bbb7bfa711b..70f2d183e87bed3f443e7ace92b824eb874c0aad 100644 (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>
index 5e1141425f7246d8cb8c0a97e9ea812f42b00859..58f68ce9e1ed7da68f0c51a179de5ea160f90066 100644 (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>