1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // UNSUPPORTED: libcpp-has-no-threads 10 11 // <condition_variable> 12 13 // class condition_variable; 14 15 // template <class Clock, class Duration> 16 // cv_status 17 // wait_until(unique_lock<mutex>& lock, 18 // const chrono::time_point<Clock, Duration>& abs_time); 19 20 #include <condition_variable> 21 #include <mutex> 22 #include <thread> 23 #include <chrono> 24 #include <cassert> 25 26 #include "make_test_thread.h" 27 #include "test_macros.h" 28 29 struct TestClock 30 { 31 typedef std::chrono::milliseconds duration; 32 typedef duration::rep rep; 33 typedef duration::period period; 34 typedef std::chrono::time_point<TestClock> time_point; 35 static const bool is_steady = true; 36 nowTestClock37 static time_point now() 38 { 39 using namespace std::chrono; 40 return time_point(duration_cast<duration>( 41 steady_clock::now().time_since_epoch() 42 )); 43 } 44 }; 45 46 std::condition_variable cv; 47 std::mutex mut; 48 49 int test1 = 0; 50 int test2 = 0; 51 52 int runs = 0; 53 54 template <typename Clock> f()55void f() 56 { 57 std::unique_lock<std::mutex> lk(mut); 58 assert(test2 == 0); 59 test1 = 1; 60 cv.notify_one(); 61 typename Clock::time_point t0 = Clock::now(); 62 typename Clock::time_point t = t0 + std::chrono::milliseconds(250); 63 while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout) 64 ; 65 typename Clock::time_point t1 = Clock::now(); 66 if (runs == 0) 67 { 68 assert(t1 - t0 < std::chrono::milliseconds(250)); 69 assert(test2 != 0); 70 } 71 else 72 { 73 assert(t1 - t0 - std::chrono::milliseconds(250) < std::chrono::milliseconds(50)); 74 assert(test2 == 0); 75 } 76 ++runs; 77 } 78 79 template <typename Clock> run_test()80void run_test() 81 { 82 runs = 0; 83 test1 = 0; 84 test2 = 0; 85 { 86 std::unique_lock<std::mutex>lk(mut); 87 std::thread t = support::make_test_thread(f<Clock>); 88 assert(test1 == 0); 89 while (test1 == 0) 90 cv.wait(lk); 91 assert(test1 != 0); 92 test2 = 1; 93 lk.unlock(); 94 cv.notify_one(); 95 t.join(); 96 } 97 test1 = 0; 98 test2 = 0; 99 { 100 std::unique_lock<std::mutex>lk(mut); 101 std::thread t = support::make_test_thread(f<Clock>); 102 assert(test1 == 0); 103 while (test1 == 0) 104 cv.wait(lk); 105 assert(test1 != 0); 106 lk.unlock(); 107 t.join(); 108 } 109 } 110 main(int,char **)111int main(int, char**) 112 { 113 run_test<TestClock>(); 114 run_test<std::chrono::steady_clock>(); 115 run_test<std::chrono::system_clock>(); 116 return 0; 117 } 118