From 6ce71d2dada6334d6d11cbf51cdac42f40ce12dd Mon Sep 17 00:00:00 2001 From: David Zarzycki Date: Wed, 3 Jun 2020 10:20:37 -0400 Subject: [PATCH] [libcxx testing] Fix more bogus timeouts: condvarany/notify_all.pass.cpp On slow/busy machines, timing cannot be guaranteed. --- .../notify_all.pass.cpp | 63 +++++++++------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp index 0a3328b..ebac642 100644 --- a/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp +++ b/libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "test_macros.h" @@ -28,49 +29,37 @@ typedef std::unique_lock L1; L0 m0; -int test0 = 0; -int test1 = 0; -int test2 = 0; +const unsigned threadCount = 2; +bool pleaseExit = false; +std::atomic notReady; -void f1() -{ - L1 lk(m0); - assert(test1 == 0); - while (test1 == 0) - cv.wait(lk); - assert(test1 == 1); - test1 = 2; -} - -void f2() -{ - L1 lk(m0); - assert(test2 == 0); - while (test2 == 0) - cv.wait(lk); - assert(test2 == 1); - test2 = 2; +void helper() { + L1 lk(m0); + --notReady; + while (pleaseExit == false) + cv.wait(lk); } int main(int, char**) { - std::thread t1(f1); - std::thread t2(f2); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - { - L1 lk(m0); - test1 = 1; - test2 = 1; - } + notReady = threadCount; + std::vector threads; + for (unsigned i = 0; i < threadCount; i++) + threads.push_back(std::thread(helper)); + { + while (notReady > 0) + std::this_thread::yield(); + // At this point, both threads have had a chance to acquire the lock and are + // either waiting on the condition variable or about to wait. + L1 lk(m0); + pleaseExit = true; + // POSIX does not guarantee reliable scheduling if notify_all is called + // without the lock being held. cv.notify_all(); - { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - L1 lk(m0); - } - t1.join(); - t2.join(); - assert(test1 == 2); - assert(test2 == 2); + } + // The test will hang if not all of the threads were woken. + for (unsigned i = 0; i < threadCount; i++) + threads[i].join(); return 0; } -- 2.7.4