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