15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
35a83710eSEric Fiselier //                     The LLVM Compiler Infrastructure
45a83710eSEric Fiselier //
55a83710eSEric Fiselier // This file is dual licensed under the MIT and the University of Illinois Open
65a83710eSEric Fiselier // Source Licenses. See LICENSE.TXT for details.
75a83710eSEric Fiselier //
85a83710eSEric Fiselier //===----------------------------------------------------------------------===//
95a83710eSEric Fiselier //
105a83710eSEric Fiselier // UNSUPPORTED: libcpp-has-no-threads
115a83710eSEric Fiselier 
125a83710eSEric Fiselier // <condition_variable>
135a83710eSEric Fiselier 
145a83710eSEric Fiselier // class condition_variable;
155a83710eSEric Fiselier 
165a83710eSEric Fiselier // void notify_one();
175a83710eSEric Fiselier 
185a83710eSEric Fiselier #include <condition_variable>
195a83710eSEric Fiselier #include <mutex>
205a83710eSEric Fiselier #include <thread>
215a83710eSEric Fiselier #include <cassert>
225a83710eSEric Fiselier 
23*10967a6eSEric Fiselier #include "test_atomic.h"
24*10967a6eSEric Fiselier 
255a83710eSEric Fiselier std::condition_variable cv;
265a83710eSEric Fiselier std::mutex mut;
275a83710eSEric Fiselier 
28*10967a6eSEric Fiselier AtomicInt test1(0);
29*10967a6eSEric Fiselier AtomicInt test2(0);
305a83710eSEric Fiselier 
315a83710eSEric Fiselier void f1()
325a83710eSEric Fiselier {
335a83710eSEric Fiselier     std::unique_lock<std::mutex> lk(mut);
345a83710eSEric Fiselier     assert(test1 == 0);
355a83710eSEric Fiselier     while (test1 == 0)
365a83710eSEric Fiselier         cv.wait(lk);
375a83710eSEric Fiselier     assert(test1 == 1);
385a83710eSEric Fiselier     test1 = 2;
395a83710eSEric Fiselier }
405a83710eSEric Fiselier 
415a83710eSEric Fiselier void f2()
425a83710eSEric Fiselier {
435a83710eSEric Fiselier     std::unique_lock<std::mutex> lk(mut);
445a83710eSEric Fiselier     assert(test2 == 0);
455a83710eSEric Fiselier     while (test2 == 0)
465a83710eSEric Fiselier         cv.wait(lk);
475a83710eSEric Fiselier     assert(test2 == 1);
485a83710eSEric Fiselier     test2 = 2;
495a83710eSEric Fiselier }
505a83710eSEric Fiselier 
515a83710eSEric Fiselier int main()
525a83710eSEric Fiselier {
535a83710eSEric Fiselier     std::thread t1(f1);
545a83710eSEric Fiselier     std::thread t2(f2);
555a83710eSEric Fiselier     std::this_thread::sleep_for(std::chrono::milliseconds(100));
565a83710eSEric Fiselier     {
575a83710eSEric Fiselier         std::unique_lock<std::mutex>lk(mut);
585a83710eSEric Fiselier         test1 = 1;
595a83710eSEric Fiselier         test2 = 1;
605a83710eSEric Fiselier     }
615a83710eSEric Fiselier     cv.notify_one();
625a83710eSEric Fiselier     {
635a83710eSEric Fiselier         std::this_thread::sleep_for(std::chrono::milliseconds(100));
645a83710eSEric Fiselier         std::unique_lock<std::mutex>lk(mut);
655a83710eSEric Fiselier     }
665a83710eSEric Fiselier     if (test1 == 2)
675a83710eSEric Fiselier     {
68*10967a6eSEric Fiselier         assert(test2 == 1);
695a83710eSEric Fiselier         t1.join();
705a83710eSEric Fiselier         test1 = 0;
715a83710eSEric Fiselier     }
725a83710eSEric Fiselier     else if (test2 == 2)
735a83710eSEric Fiselier     {
74*10967a6eSEric Fiselier         assert(test1 == 1);
755a83710eSEric Fiselier         t2.join();
765a83710eSEric Fiselier         test2 = 0;
775a83710eSEric Fiselier     }
785a83710eSEric Fiselier     else
795a83710eSEric Fiselier         assert(false);
805a83710eSEric Fiselier     cv.notify_one();
815a83710eSEric Fiselier     {
825a83710eSEric Fiselier         std::this_thread::sleep_for(std::chrono::milliseconds(100));
835a83710eSEric Fiselier         std::unique_lock<std::mutex>lk(mut);
845a83710eSEric Fiselier     }
855a83710eSEric Fiselier     if (test1 == 2)
865a83710eSEric Fiselier     {
87*10967a6eSEric Fiselier         assert(test2 == 0);
885a83710eSEric Fiselier         t1.join();
895a83710eSEric Fiselier         test1 = 0;
905a83710eSEric Fiselier     }
915a83710eSEric Fiselier     else if (test2 == 2)
925a83710eSEric Fiselier     {
93*10967a6eSEric Fiselier         assert(test1 == 0);
945a83710eSEric Fiselier         t2.join();
955a83710eSEric Fiselier         test2 = 0;
965a83710eSEric Fiselier     }
975a83710eSEric Fiselier     else
985a83710eSEric Fiselier         assert(false);
995a83710eSEric Fiselier }
100