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, class Predicate> 17 // bool 18 // wait_until(unique_lock<mutex>& 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 cv; 58 std::mutex mut; 59 60 int test1 = 0; 61 int test2 = 0; 62 63 int runs = 0; 64 65 void f() 66 { 67 std::unique_lock<std::mutex> lk(mut); 68 assert(test2 == 0); 69 test1 = 1; 70 cv.notify_one(); 71 Clock::time_point t0 = Clock::now(); 72 Clock::time_point t = t0 + Clock::duration(250); 73 bool r = cv.wait_until(lk, t, Pred(test2)); 74 Clock::time_point t1 = Clock::now(); 75 if (runs == 0) 76 { 77 assert(t1 - t0 < Clock::duration(250)); 78 assert(test2 != 0); 79 assert(r); 80 } 81 else 82 { 83 assert(t1 - t0 - Clock::duration(250) < Clock::duration(50)); 84 assert(test2 == 0); 85 assert(!r); 86 } 87 ++runs; 88 } 89 90 int main(int, char**) 91 { 92 { 93 std::unique_lock<std::mutex> lk(mut); 94 std::thread t = support::make_test_thread(f); 95 assert(test1 == 0); 96 while (test1 == 0) 97 cv.wait(lk); 98 assert(test1 != 0); 99 test2 = 1; 100 lk.unlock(); 101 cv.notify_one(); 102 t.join(); 103 } 104 test1 = 0; 105 test2 = 0; 106 { 107 std::unique_lock<std::mutex> lk(mut); 108 std::thread t = support::make_test_thread(f); 109 assert(test1 == 0); 110 while (test1 == 0) 111 cv.wait(lk); 112 assert(test1 != 0); 113 lk.unlock(); 114 t.join(); 115 } 116 117 return 0; 118 } 119