libstdc++: Fix testsuite helper functions [PR 97936]
authorJonathan Wakely <jwakely@redhat.com>
Wed, 25 Nov 2020 14:39:54 +0000 (14:39 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 25 Nov 2020 18:24:12 +0000 (18:24 +0000)
This fixes a race condition in the util/atomic/wait_notify_util.h header
used by several tests, which should make the tests work properly.

libstdc++-v3/ChangeLog:

PR libstdc++/97936
* testsuite/29_atomics/atomic/wait_notify/bool.cc: Re-eneable
test.
* testsuite/29_atomics/atomic/wait_notify/generic.cc: Likewise.
* testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise.
* testsuite/29_atomics/atomic_float/wait_notify.cc: Likewise.
* testsuite/29_atomics/atomic_integral/wait_notify.cc: Likewise.
* testsuite/util/atomic/wait_notify_util.h: Fix missed
notifications by making the new thread wait until the parent
thread is waiting on the condition variable.

libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc
libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc
libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
libstdc++-v3/testsuite/29_atomics/atomic_float/wait_notify.cc
libstdc++-v3/testsuite/29_atomics/atomic_integral/wait_notify.cc
libstdc++-v3/testsuite/util/atomic/wait_notify_util.h

index 29781c6e135733040adc51c82d5356f27a9e4af4..c14a2391d68bd9ce99252238a32bbea96b0dfc2b 100644 (file)
@@ -2,7 +2,6 @@
 // { dg-do run { target c++2a } }
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
-// { dg-skip-if "broken" { ! *-*-*linux } }
 
 // Copyright (C) 2020 Free Software Foundation, Inc.
 //
index 629556a9d2d0090837924e4e3d1a315c02040726..988fe7b334f3fe273e519affc4cf330f82c79406 100644 (file)
@@ -2,7 +2,6 @@
 // { dg-do run { target c++2a } }
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
-// { dg-skip-if "broken" { ! *-*-*linux } }
 
 // Copyright (C) 2020 Free Software Foundation, Inc.
 //
index f54961f893d48265d6514550749bae1aa9dc881a..87830236e0ee6df2e7d117948e375f6a452e438e 100644 (file)
@@ -2,7 +2,6 @@
 // { dg-do run { target c++2a } }
 // { dg-additional-options "-pthread" { target pthread } }
 // { dg-require-gthreads "" }
-// { dg-skip-if "broken" { ! *-*-*linux } }
 
 // Copyright (C) 2020 Free Software Foundation, Inc.
 //
index 763d3e77159cbc75a567611b0e6e0f85abf5720d..991713fbcdee6f41cfe52a03b1f821b0cf9bf3d1 100644 (file)
@@ -2,7 +2,6 @@
 // { dg-do run { target c++2a } }
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
-// { dg-skip-if "broken" { ! *-*-*linux } }
 
 // Copyright (C) 2020 Free Software Foundation, Inc.
 //
index 8f9e4a39a21ff35af2954986f2f1095be0b45c62..134eff39e1b153ba083a072972a6b6e24108cf54 100644 (file)
@@ -3,7 +3,6 @@
 // { dg-require-gthreads "" }
 // { dg-additional-options "-pthread" { target pthread } }
 // { dg-add-options libatomic }
-// { dg-skip-if "broken" { ! *-*-*linux } }
 
 // Copyright (C) 2020 Free Software Foundation, Inc.
 //
index 762583cf8c76eaaecfea3308e127e7581b14e3ab..c65379cba619222703e79017da5687ef4dcf7e18 100644 (file)
@@ -3,7 +3,6 @@
 // { dg-require-gthreads "" }
 // { dg-add-options libatomic }
 // { dg-additional-options "-pthread" { target pthread } }
-// { dg-skip-if "broken" { *-*-* } }
 
 // Copyright (C) 2020 Free Software Foundation, Inc.
 //
index a319e8b60a696fa65a8eda6f6e30f7b683527a8e..f5fff4af4e4936f26b03fa88d3a4e77e8e6bfae9 100644 (file)
@@ -34,16 +34,20 @@ Tp check_wait_notify(Tp val1, Tp val2)
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   std::atomic<Tp> a(val1);
   std::thread t([&]
                {
+                 {
+                   // This ensures we block until cv.wait(l) starts.
+                   std::lock_guard<std::mutex> ll(m);
+                 }
                  cv.notify_one();
                  a.wait(val1);
                  if (a.load() != val2)
                    a = val1;
                });
-  std::unique_lock<std::mutex> l(m);
   cv.wait(l);
   std::this_thread::sleep_for(100ms);
   a.store(val2);
@@ -59,10 +63,15 @@ Tp check_wait_notify(Tp val1, Tp val2)
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   std::atomic<Tp> a(val1);
   std::thread t([&]
                {
+                 {
+                   // This ensures we block until cv.wait(l) starts.
+                   std::lock_guard<std::mutex> ll(m);
+                 }
                  cv.notify_one();
                  a.wait(val1);
                  auto v = a.load();
@@ -70,7 +79,6 @@ Tp check_wait_notify(Tp val1, Tp val2)
                  if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
                    a = val1;
                });
-  std::unique_lock<std::mutex> l(m);
   cv.wait(l);
   std::this_thread::sleep_for(100ms);
   a.store(val2);
@@ -87,16 +95,20 @@ Tp check_atomic_wait_notify(Tp val1, Tp val2)
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   std::atomic<Tp> a(val1);
   std::thread t([&]
                {
+                 {
+                   // This ensures we block until cv.wait(l) starts.
+                   std::lock_guard<std::mutex> ll(m);
+                 }
                  cv.notify_one();
                  std::atomic_wait(&a, val1);
                  if (a.load() != val2)
                    a = val1;
                });
-  std::unique_lock<std::mutex> l(m);
   cv.wait(l);
   std::this_thread::sleep_for(100ms);
   a.store(val2);
@@ -112,10 +124,15 @@ Tp check_atomic_wait_notify(Tp val1, Tp val2)
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   std::atomic<Tp> a(val1);
   std::thread t([&]
                {
+                 {
+                   // This ensures we block until cv.wait(l) starts.
+                   std::lock_guard<std::mutex> ll(m);
+                 }
                  cv.notify_one();
                  std::atomic_wait(&a, val1);
                  auto v = a.load();
@@ -123,7 +140,6 @@ Tp check_atomic_wait_notify(Tp val1, Tp val2)
                  if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
                    a = val1;
                });
-  std::unique_lock<std::mutex> l(m);
   cv.wait(l);
   std::this_thread::sleep_for(100ms);
   a.store(val2);