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