Skip to content

Commit 6ce71d2

Browse files
committed
[libcxx testing] Fix more bogus timeouts: condvarany/notify_all.pass.cpp
On slow/busy machines, timing cannot be guaranteed.
1 parent d9d28b3 commit 6ce71d2

File tree

1 file changed

+26
-37
lines changed

1 file changed

+26
-37
lines changed

libcxx/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <condition_variable>
1818
#include <mutex>
1919
#include <thread>
20+
#include <vector>
2021
#include <cassert>
2122

2223
#include "test_macros.h"
@@ -28,49 +29,37 @@ typedef std::unique_lock<L0> L1;
2829

2930
L0 m0;
3031

31-
int test0 = 0;
32-
int test1 = 0;
33-
int test2 = 0;
32+
const unsigned threadCount = 2;
33+
bool pleaseExit = false;
34+
std::atomic<unsigned> notReady;
3435

35-
void f1()
36-
{
37-
L1 lk(m0);
38-
assert(test1 == 0);
39-
while (test1 == 0)
40-
cv.wait(lk);
41-
assert(test1 == 1);
42-
test1 = 2;
43-
}
44-
45-
void f2()
46-
{
47-
L1 lk(m0);
48-
assert(test2 == 0);
49-
while (test2 == 0)
50-
cv.wait(lk);
51-
assert(test2 == 1);
52-
test2 = 2;
36+
void helper() {
37+
L1 lk(m0);
38+
--notReady;
39+
while (pleaseExit == false)
40+
cv.wait(lk);
5341
}
5442

5543
int main(int, char**)
5644
{
57-
std::thread t1(f1);
58-
std::thread t2(f2);
59-
std::this_thread::sleep_for(std::chrono::milliseconds(100));
60-
{
61-
L1 lk(m0);
62-
test1 = 1;
63-
test2 = 1;
64-
}
45+
notReady = threadCount;
46+
std::vector<std::thread> threads;
47+
for (unsigned i = 0; i < threadCount; i++)
48+
threads.push_back(std::thread(helper));
49+
{
50+
while (notReady > 0)
51+
std::this_thread::yield();
52+
// At this point, both threads have had a chance to acquire the lock and are
53+
// either waiting on the condition variable or about to wait.
54+
L1 lk(m0);
55+
pleaseExit = true;
56+
// POSIX does not guarantee reliable scheduling if notify_all is called
57+
// without the lock being held.
6558
cv.notify_all();
66-
{
67-
std::this_thread::sleep_for(std::chrono::milliseconds(100));
68-
L1 lk(m0);
69-
}
70-
t1.join();
71-
t2.join();
72-
assert(test1 == 2);
73-
assert(test2 == 2);
59+
}
60+
// The test will hang if not all of the threads were woken.
61+
for (unsigned i = 0; i < threadCount; i++)
62+
threads[i].join();
7463

7564
return 0;
7665
}

0 commit comments

Comments
 (0)