[mlir][acc] Introduce MappableType interface (#122146)
[llvm-project.git] / libcxx / test / std / thread / thread.condition / thread.condition.condvarany / wait_for_token_pred.pass.cpp
blob9b6f34a7e8a3ce09a03e1add2c5d73bf72e4f1a3
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 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // XFAIL: availability-synchronization_library-missing
13 // <condition_variable>
15 // class condition_variable_any;
17 // template<class Lock, class Rep, class Period, class Predicate>
18 // bool wait_for(Lock& lock, stop_token stoken,
19 // const chrono::duration<Rep, Period>& rel_time, Predicate pred);
21 #include <atomic>
22 #include <cassert>
23 #include <chrono>
24 #include <concepts>
25 #include <condition_variable>
26 #include <functional>
27 #include <mutex>
28 #include <shared_mutex>
29 #include <stop_token>
30 #include <thread>
32 #include "helpers.h"
33 #include "make_test_thread.h"
34 #include "test_macros.h"
36 template <class Mutex, class Lock>
37 void test() {
38 using namespace std::chrono_literals;
40 // stop_requested before hand
42 std::stop_source ss;
43 std::condition_variable_any cv;
44 Mutex mutex;
45 Lock lock{mutex};
46 ss.request_stop();
48 ElapsedTimeCheck check(1min);
50 // [Note 4: The returned value indicates whether the predicate evaluated to true
51 // regardless of whether the timeout was triggered or a stop request was made.]
52 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), -1h, []() { return false; });
53 assert(!r1);
55 std::same_as<bool> auto r2 = cv.wait_for(lock, ss.get_token(), 1h, []() { return false; });
56 assert(!r2);
58 std::same_as<bool> auto r3 = cv.wait_for(lock, ss.get_token(), -1h, []() { return true; });
59 assert(r3);
61 std::same_as<bool> auto r4 = cv.wait_for(lock, ss.get_token(), 1h, []() { return true; });
62 assert(r4);
64 // Postconditions: lock is locked by the calling thread.
65 assert(lock.owns_lock());
68 // no stop request, pred was true
70 std::stop_source ss;
71 std::condition_variable_any cv;
72 Mutex mutex;
73 Lock lock{mutex};
75 ElapsedTimeCheck check(1min);
77 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), -1h, []() { return true; });
78 assert(r1);
80 std::same_as<bool> auto r2 = cv.wait_for(lock, ss.get_token(), 1h, []() { return true; });
81 assert(r2);
84 // no stop request, pred was false, abs_time was in the past
86 std::stop_source ss;
87 std::condition_variable_any cv;
88 Mutex mutex;
89 Lock lock{mutex};
91 ElapsedTimeCheck check(1min);
93 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), -1h, []() { return false; });
94 assert(!r1);
97 // no stop request, pred was false until timeout
99 std::stop_source ss;
100 std::condition_variable_any cv;
101 Mutex mutex;
102 Lock lock{mutex};
104 auto old_time = std::chrono::steady_clock::now();
106 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), 2ms, [&]() { return false; });
108 assert((std::chrono::steady_clock::now() - old_time) >= 2ms);
109 assert(!r1);
112 // no stop request, pred was false, changed to true before timeout
114 std::stop_source ss;
115 std::condition_variable_any cv;
116 Mutex mutex;
117 Lock lock{mutex};
119 bool flag = false;
120 auto thread = support::make_test_thread([&]() {
121 std::this_thread::sleep_for(2ms);
122 std::unique_lock<Mutex> lock2{mutex};
123 flag = true;
124 cv.notify_all();
127 ElapsedTimeCheck check(10min);
129 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), 1h, [&]() { return flag; });
130 assert(flag);
131 assert(r1);
133 thread.join();
136 // stop request comes while waiting
138 std::stop_source ss;
139 std::condition_variable_any cv;
140 Mutex mutex;
141 Lock lock{mutex};
143 std::atomic_bool start = false;
144 std::atomic_bool done = false;
145 auto thread = support::make_test_thread([&]() {
146 start.wait(false);
147 ss.request_stop();
149 while (!done) {
150 cv.notify_all();
151 std::this_thread::sleep_for(2ms);
155 ElapsedTimeCheck check(10min);
157 std::same_as<bool> auto r = cv.wait_for(lock, ss.get_token(), 1h, [&]() {
158 start.store(true);
159 start.notify_all();
160 return false;
162 assert(!r);
163 done = true;
164 thread.join();
166 assert(lock.owns_lock());
169 // #76807 Hangs in std::condition_variable_any when used with std::stop_token
171 class MyThread {
172 public:
173 MyThread() {
174 thread_ = support::make_test_jthread([this](std::stop_token st) {
175 while (!st.stop_requested()) {
176 std::unique_lock lock{m_};
177 cv_.wait_for(lock, st, 1h, [] { return false; });
182 private:
183 std::mutex m_;
184 std::condition_variable_any cv_;
185 std::jthread thread_;
188 ElapsedTimeCheck check(10min);
190 [[maybe_unused]] MyThread my_thread;
193 // request_stop potentially in-between check and wait
195 std::stop_source ss;
196 std::condition_variable_any cv;
197 Mutex mutex;
198 Lock lock{mutex};
200 std::atomic_bool pred_started = false;
201 std::atomic_bool request_stop_called = false;
202 auto thread = support::make_test_thread([&]() {
203 pred_started.wait(false);
204 ss.request_stop();
205 request_stop_called.store(true);
206 request_stop_called.notify_all();
209 ElapsedTimeCheck check(10min);
211 std::same_as<bool> auto r = cv.wait_for(lock, ss.get_token(), 1h, [&]() {
212 pred_started.store(true);
213 pred_started.notify_all();
214 request_stop_called.wait(false);
215 return false;
217 assert(!r);
218 thread.join();
220 assert(lock.owns_lock());
223 #if !defined(TEST_HAS_NO_EXCEPTIONS)
224 // Throws: Any exception thrown by pred.
226 std::stop_source ss;
227 std::condition_variable_any cv;
228 Mutex mutex;
229 Lock lock{mutex};
231 try {
232 ElapsedTimeCheck check(10min);
233 cv.wait_for(lock, ss.get_token(), 1h, []() -> bool { throw 5; });
234 assert(false);
235 } catch (int i) {
236 assert(i == 5);
239 #endif //!defined(TEST_HAS_NO_EXCEPTIONS)
242 int main(int, char**) {
243 test<std::mutex, std::unique_lock<std::mutex>>();
244 test<std::shared_mutex, std::shared_lock<std::shared_mutex>>();
246 return 0;