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

source code of libcxx/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp