1*5a83710eSEric Fiselier //===----------------------------------------------------------------------===//
2*5a83710eSEric Fiselier //
3*5a83710eSEric Fiselier //                     The LLVM Compiler Infrastructure
4*5a83710eSEric Fiselier //
5*5a83710eSEric Fiselier // This file is dual licensed under the MIT and the University of Illinois Open
6*5a83710eSEric Fiselier // Source Licenses. See LICENSE.TXT for details.
7*5a83710eSEric Fiselier //
8*5a83710eSEric Fiselier //===----------------------------------------------------------------------===//
9*5a83710eSEric Fiselier //
10*5a83710eSEric Fiselier // UNSUPPORTED: libcpp-has-no-threads
11*5a83710eSEric Fiselier 
12*5a83710eSEric Fiselier // <condition_variable>
13*5a83710eSEric Fiselier 
14*5a83710eSEric Fiselier // class condition_variable;
15*5a83710eSEric Fiselier 
16*5a83710eSEric Fiselier // void notify_one();
17*5a83710eSEric Fiselier 
18*5a83710eSEric Fiselier #include <condition_variable>
19*5a83710eSEric Fiselier #include <mutex>
20*5a83710eSEric Fiselier #include <thread>
21*5a83710eSEric Fiselier #include <cassert>
22*5a83710eSEric Fiselier 
23*5a83710eSEric Fiselier std::condition_variable cv;
24*5a83710eSEric Fiselier std::mutex mut;
25*5a83710eSEric Fiselier 
26*5a83710eSEric Fiselier int test0 = 0;
27*5a83710eSEric Fiselier int test1 = 0;
28*5a83710eSEric Fiselier int test2 = 0;
29*5a83710eSEric Fiselier 
30*5a83710eSEric Fiselier void f1()
31*5a83710eSEric Fiselier {
32*5a83710eSEric Fiselier     std::unique_lock<std::mutex> lk(mut);
33*5a83710eSEric Fiselier     assert(test1 == 0);
34*5a83710eSEric Fiselier     while (test1 == 0)
35*5a83710eSEric Fiselier         cv.wait(lk);
36*5a83710eSEric Fiselier     assert(test1 == 1);
37*5a83710eSEric Fiselier     test1 = 2;
38*5a83710eSEric Fiselier }
39*5a83710eSEric Fiselier 
40*5a83710eSEric Fiselier void f2()
41*5a83710eSEric Fiselier {
42*5a83710eSEric Fiselier     std::unique_lock<std::mutex> lk(mut);
43*5a83710eSEric Fiselier     assert(test2 == 0);
44*5a83710eSEric Fiselier     while (test2 == 0)
45*5a83710eSEric Fiselier         cv.wait(lk);
46*5a83710eSEric Fiselier     assert(test2 == 1);
47*5a83710eSEric Fiselier     test2 = 2;
48*5a83710eSEric Fiselier }
49*5a83710eSEric Fiselier 
50*5a83710eSEric Fiselier int main()
51*5a83710eSEric Fiselier {
52*5a83710eSEric Fiselier     std::thread t1(f1);
53*5a83710eSEric Fiselier     std::thread t2(f2);
54*5a83710eSEric Fiselier     std::this_thread::sleep_for(std::chrono::milliseconds(100));
55*5a83710eSEric Fiselier     {
56*5a83710eSEric Fiselier         std::unique_lock<std::mutex>lk(mut);
57*5a83710eSEric Fiselier         test1 = 1;
58*5a83710eSEric Fiselier         test2 = 1;
59*5a83710eSEric Fiselier     }
60*5a83710eSEric Fiselier     cv.notify_one();
61*5a83710eSEric Fiselier     {
62*5a83710eSEric Fiselier         std::this_thread::sleep_for(std::chrono::milliseconds(100));
63*5a83710eSEric Fiselier         std::unique_lock<std::mutex>lk(mut);
64*5a83710eSEric Fiselier     }
65*5a83710eSEric Fiselier     if (test1 == 2)
66*5a83710eSEric Fiselier     {
67*5a83710eSEric Fiselier         t1.join();
68*5a83710eSEric Fiselier         test1 = 0;
69*5a83710eSEric Fiselier     }
70*5a83710eSEric Fiselier     else if (test2 == 2)
71*5a83710eSEric Fiselier     {
72*5a83710eSEric Fiselier         t2.join();
73*5a83710eSEric Fiselier         test2 = 0;
74*5a83710eSEric Fiselier     }
75*5a83710eSEric Fiselier     else
76*5a83710eSEric Fiselier         assert(false);
77*5a83710eSEric Fiselier     cv.notify_one();
78*5a83710eSEric Fiselier     {
79*5a83710eSEric Fiselier         std::this_thread::sleep_for(std::chrono::milliseconds(100));
80*5a83710eSEric Fiselier         std::unique_lock<std::mutex>lk(mut);
81*5a83710eSEric Fiselier     }
82*5a83710eSEric Fiselier     if (test1 == 2)
83*5a83710eSEric Fiselier     {
84*5a83710eSEric Fiselier         t1.join();
85*5a83710eSEric Fiselier         test1 = 0;
86*5a83710eSEric Fiselier     }
87*5a83710eSEric Fiselier     else if (test2 == 2)
88*5a83710eSEric Fiselier     {
89*5a83710eSEric Fiselier         t2.join();
90*5a83710eSEric Fiselier         test2 = 0;
91*5a83710eSEric Fiselier     }
92*5a83710eSEric Fiselier     else
93*5a83710eSEric Fiselier         assert(false);
94*5a83710eSEric Fiselier }
95