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