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; 14 15 // template <class Clock, class Duration> 16 // cv_status 17 // wait_until(unique_lock<mutex>& lock, 18 // const chrono::time_point<Clock, Duration>& abs_time); 19 20 #include <condition_variable> 21 #include <mutex> 22 #include <thread> 23 #include <chrono> 24 #include <cassert> 25 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 36 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 cv; 46 std::mutex mut; 47 48 int test1 = 0; 49 int test2 = 0; 50 51 int runs = 0; 52 53 void f() 54 { 55 std::unique_lock<std::mutex> lk(mut); 56 assert(test2 == 0); 57 test1 = 1; 58 cv.notify_one(); 59 Clock::time_point t0 = Clock::now(); 60 Clock::time_point t = t0 + Clock::duration(250); 61 while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout) 62 ; 63 Clock::time_point t1 = Clock::now(); 64 if (runs == 0) 65 { 66 assert(t1 - t0 < Clock::duration(250)); 67 assert(test2 != 0); 68 } 69 else 70 { 71 assert(t1 - t0 - Clock::duration(250) < Clock::duration(50)); 72 assert(test2 == 0); 73 } 74 ++runs; 75 } 76 77 int main(int, char**) 78 { 79 { 80 std::unique_lock<std::mutex>lk(mut); 81 std::thread t(f); 82 assert(test1 == 0); 83 while (test1 == 0) 84 cv.wait(lk); 85 assert(test1 != 0); 86 test2 = 1; 87 lk.unlock(); 88 cv.notify_one(); 89 t.join(); 90 } 91 test1 = 0; 92 test2 = 0; 93 { 94 std::unique_lock<std::mutex>lk(mut); 95 std::thread t(f); 96 assert(test1 == 0); 97 while (test1 == 0) 98 cv.wait(lk); 99 assert(test1 != 0); 100 lk.unlock(); 101 t.join(); 102 } 103 104 return 0; 105 } 106