libstdc++: Fix testsuite helper functions [PR 97936]

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.
This commit is contained in:
Jonathan Wakely 2020-11-25 14:39:54 +00:00
parent aec2d68491
commit f76cad692a
7 changed files with 20 additions and 10 deletions

View File

@ -2,7 +2,6 @@
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } } // { dg-additional-options "-pthread" { target pthread } }
// { dg-skip-if "broken" { ! *-*-*linux } }
// Copyright (C) 2020 Free Software Foundation, Inc. // Copyright (C) 2020 Free Software Foundation, Inc.
// //

View File

@ -2,7 +2,6 @@
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } } // { dg-additional-options "-pthread" { target pthread } }
// { dg-skip-if "broken" { ! *-*-*linux } }
// Copyright (C) 2020 Free Software Foundation, Inc. // Copyright (C) 2020 Free Software Foundation, Inc.
// //

View File

@ -2,7 +2,6 @@
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
// { dg-additional-options "-pthread" { target pthread } } // { dg-additional-options "-pthread" { target pthread } }
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-skip-if "broken" { ! *-*-*linux } }
// Copyright (C) 2020 Free Software Foundation, Inc. // Copyright (C) 2020 Free Software Foundation, Inc.
// //

View File

@ -2,7 +2,6 @@
// { dg-do run { target c++2a } } // { dg-do run { target c++2a } }
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } } // { dg-additional-options "-pthread" { target pthread } }
// { dg-skip-if "broken" { ! *-*-*linux } }
// Copyright (C) 2020 Free Software Foundation, Inc. // Copyright (C) 2020 Free Software Foundation, Inc.
// //

View File

@ -3,7 +3,6 @@
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-additional-options "-pthread" { target pthread } } // { dg-additional-options "-pthread" { target pthread } }
// { dg-add-options libatomic } // { dg-add-options libatomic }
// { dg-skip-if "broken" { ! *-*-*linux } }
// Copyright (C) 2020 Free Software Foundation, Inc. // Copyright (C) 2020 Free Software Foundation, Inc.
// //

View File

@ -3,7 +3,6 @@
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-add-options libatomic } // { dg-add-options libatomic }
// { dg-additional-options "-pthread" { target pthread } } // { dg-additional-options "-pthread" { target pthread } }
// { dg-skip-if "broken" { *-*-* } }
// Copyright (C) 2020 Free Software Foundation, Inc. // Copyright (C) 2020 Free Software Foundation, Inc.
// //

View File

@ -34,16 +34,20 @@ Tp check_wait_notify(Tp val1, Tp val2)
std::mutex m; std::mutex m;
std::condition_variable cv; std::condition_variable cv;
std::unique_lock<std::mutex> l(m);
std::atomic<Tp> a(val1); std::atomic<Tp> a(val1);
std::thread t([&] std::thread t([&]
{ {
{
// This ensures we block until cv.wait(l) starts.
std::lock_guard<std::mutex> ll(m);
}
cv.notify_one(); cv.notify_one();
a.wait(val1); a.wait(val1);
if (a.load() != val2) if (a.load() != val2)
a = val1; a = val1;
}); });
std::unique_lock<std::mutex> l(m);
cv.wait(l); cv.wait(l);
std::this_thread::sleep_for(100ms); std::this_thread::sleep_for(100ms);
a.store(val2); a.store(val2);
@ -59,10 +63,15 @@ Tp check_wait_notify(Tp val1, Tp val2)
std::mutex m; std::mutex m;
std::condition_variable cv; std::condition_variable cv;
std::unique_lock<std::mutex> l(m);
std::atomic<Tp> a(val1); std::atomic<Tp> a(val1);
std::thread t([&] std::thread t([&]
{ {
{
// This ensures we block until cv.wait(l) starts.
std::lock_guard<std::mutex> ll(m);
}
cv.notify_one(); cv.notify_one();
a.wait(val1); a.wait(val1);
auto v = a.load(); auto v = a.load();
@ -70,7 +79,6 @@ Tp check_wait_notify(Tp val1, Tp val2)
if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0) if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
a = val1; a = val1;
}); });
std::unique_lock<std::mutex> l(m);
cv.wait(l); cv.wait(l);
std::this_thread::sleep_for(100ms); std::this_thread::sleep_for(100ms);
a.store(val2); a.store(val2);
@ -87,16 +95,20 @@ Tp check_atomic_wait_notify(Tp val1, Tp val2)
std::mutex m; std::mutex m;
std::condition_variable cv; std::condition_variable cv;
std::unique_lock<std::mutex> l(m);
std::atomic<Tp> a(val1); std::atomic<Tp> a(val1);
std::thread t([&] std::thread t([&]
{ {
{
// This ensures we block until cv.wait(l) starts.
std::lock_guard<std::mutex> ll(m);
}
cv.notify_one(); cv.notify_one();
std::atomic_wait(&a, val1); std::atomic_wait(&a, val1);
if (a.load() != val2) if (a.load() != val2)
a = val1; a = val1;
}); });
std::unique_lock<std::mutex> l(m);
cv.wait(l); cv.wait(l);
std::this_thread::sleep_for(100ms); std::this_thread::sleep_for(100ms);
a.store(val2); a.store(val2);
@ -112,10 +124,15 @@ Tp check_atomic_wait_notify(Tp val1, Tp val2)
std::mutex m; std::mutex m;
std::condition_variable cv; std::condition_variable cv;
std::unique_lock<std::mutex> l(m);
std::atomic<Tp> a(val1); std::atomic<Tp> a(val1);
std::thread t([&] std::thread t([&]
{ {
{
// This ensures we block until cv.wait(l) starts.
std::lock_guard<std::mutex> ll(m);
}
cv.notify_one(); cv.notify_one();
std::atomic_wait(&a, val1); std::atomic_wait(&a, val1);
auto v = a.load(); 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) if (__builtin_memcmp(&v, &val2, sizeof(Tp)) != 0)
a = val1; a = val1;
}); });
std::unique_lock<std::mutex> l(m);
cv.wait(l); cv.wait(l);
std::this_thread::sleep_for(100ms); std::this_thread::sleep_for(100ms);
a.store(val2); a.store(val2);