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