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