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