libstdc++: Fix some more deadlocks in tests [PR 97936]
authorJonathan Wakely <jwakely@redhat.com>
Thu, 26 Nov 2020 12:55:47 +0000 (12:55 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 26 Nov 2020 16:15:52 +0000 (16:15 +0000)
The missed notifications fixed in r11-5383 also happen in some other
tests which have similar code.

libstdc++-v3/ChangeLog:

PR libstdc++/97936
* testsuite/29_atomics/atomic/wait_notify/bool.cc: Fix missed
notifications by making the new thread wait until the parent
thread is waiting on the condition variable.
* testsuite/29_atomics/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: Likewise.
* testsuite/29_atomics/atomic_ref/wait_notify.cc: Likewise.

libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.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_ref/wait_notify.cc

index c14a2391d68bd9ce99252238a32bbea96b0dfc2b..1fc01491173789319654e3dff56b82ce06f77bc7 100644 (file)
@@ -36,11 +36,16 @@ main ()
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   std::atomic<bool> a(false);
   std::atomic<bool> b(false);
   std::thread t([&]
                {
+                 {
+                   // This ensures we block until cv.wait(l) starts.
+                   std::lock_guard<std::mutex> ll(m);
+                 }
                  cv.notify_one();
                  a.wait(false);
                  if (a.load())
@@ -48,7 +53,6 @@ main ()
                      b.store(true);
                    }
                });
-  std::unique_lock<std::mutex> l(m);
   cv.wait(l);
   std::this_thread::sleep_for(100ms);
   a.store(true);
index 87830236e0ee6df2e7d117948e375f6a452e438e..3b699e9133b262b5c2e2583c7afde550187ecccb 100644 (file)
@@ -36,6 +36,7 @@ main ()
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   long aa;
   long bb;
@@ -43,12 +44,15 @@ main ()
   std::atomic<long*> a(nullptr);
   std::thread t([&]
                {
+                 {
+                   // This ensures we block until cv.wait(l) starts.
+                   std::lock_guard<std::mutex> ll(m);
+                 }
                  cv.notify_one();
                  a.wait(nullptr);
                  if (a.load() == &aa)
                    a.store(&bb);
                });
-  std::unique_lock<std::mutex> l(m);
   cv.wait(l);
   std::this_thread::sleep_for(100ms);
   a.store(&aa);
index 991713fbcdee6f41cfe52a03b1f821b0cf9bf3d1..5d5e06dde31caf6ebdb3b09a9c32edc379bfa79c 100644 (file)
@@ -36,18 +36,22 @@ main()
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   std::atomic_flag a;
   std::atomic_flag b;
   std::thread t([&]
                {
+                 {
+                   // This ensures we block until cv.wait(l) starts.
+                   std::lock_guard<std::mutex> ll(m);
+                 }
                  cv.notify_one();
                  a.wait(false);
                  b.test_and_set();
                  b.notify_one();
                });
 
-  std::unique_lock<std::mutex> l(m);
   cv.wait(l);
   std::this_thread::sleep_for(100ms);
   a.test_and_set();
index b38fc206d468fa844495809f11b7cc7c9bc6a75f..bc5a7d0d8bf91654e5e074947a8dde0fc721e16a 100644 (file)
@@ -37,17 +37,21 @@ Tp check_wait_notify(Tp val1, Tp val2)
 
   std::mutex m;
   std::condition_variable cv;
+  std::unique_lock<std::mutex> l(m);
 
   Tp aa = val1;
   std::atomic_ref<Tp> a(aa);
   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);