Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / thread / thread.condition / thread.condition.condvarany / wait_for_token_pred.pass.cpp
blobfb3f0287726eea0dc02034887ac0f1027181943a
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 // UNSUPPORTED: libcpp-has-no-experimental-stop_token
12 // XFAIL: availability-synchronization_library-missing
14 // <condition_variable>
16 // class condition_variable_any;
18 // template<class Lock, class Rep, class Period, class Predicate>
19 // bool wait_for(Lock& lock, stop_token stoken,
20 // const chrono::duration<Rep, Period>& rel_time, Predicate pred);
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 "make_test_thread.h"
33 #include "test_macros.h"
35 template <class Mutex, class Lock>
36 void test() {
37 using namespace std::chrono_literals;
39 // stop_requested before hand
41 std::stop_source ss;
42 std::condition_variable_any cv;
43 Mutex mutex;
44 Lock lock{mutex};
45 ss.request_stop();
47 // [Note 4: The returned value indicates whether the predicate evaluated to true
48 // regardless of whether the timeout was triggered or a stop request was made.]
49 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), -1h, []() { return false; });
50 assert(!r1);
52 std::same_as<bool> auto r2 = cv.wait_for(lock, ss.get_token(), 1h, []() { return false; });
53 assert(!r2);
55 std::same_as<bool> auto r3 = cv.wait_for(lock, ss.get_token(), -1h, []() { return true; });
56 assert(r3);
58 std::same_as<bool> auto r4 = cv.wait_for(lock, ss.get_token(), 1h, []() { return true; });
59 assert(r4);
61 // Postconditions: lock is locked by the calling thread.
62 assert(lock.owns_lock());
65 // no stop request, pred was true
67 std::stop_source ss;
68 std::condition_variable_any cv;
69 Mutex mutex;
70 Lock lock{mutex};
72 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), -1h, []() { return true; });
73 assert(r1);
75 std::same_as<bool> auto r2 = cv.wait_for(lock, ss.get_token(), 1h, []() { return true; });
76 assert(r2);
79 // no stop request, pred was false, abs_time was in the past
81 std::stop_source ss;
82 std::condition_variable_any cv;
83 Mutex mutex;
84 Lock lock{mutex};
86 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), -1h, []() { return false; });
87 assert(!r1);
90 // no stop request, pred was false until timeout
92 std::stop_source ss;
93 std::condition_variable_any cv;
94 Mutex mutex;
95 Lock lock{mutex};
97 auto old_time = std::chrono::steady_clock::now();
99 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), 2ms, [&]() { return false; });
101 assert((std::chrono::steady_clock::now() - old_time) >= 2ms);
102 assert(!r1);
105 // no stop request, pred was false, changed to true before timeout
107 std::stop_source ss;
108 std::condition_variable_any cv;
109 Mutex mutex;
110 Lock lock{mutex};
112 bool flag = false;
113 auto thread = support::make_test_thread([&]() {
114 std::this_thread::sleep_for(2ms);
115 Lock lock2{mutex};
116 flag = true;
117 cv.notify_all();
120 std::same_as<bool> auto r1 = cv.wait_for(lock, ss.get_token(), 1h, [&]() { return flag; });
121 assert(flag);
122 assert(r1);
124 thread.join();
127 // stop request comes while waiting
129 std::stop_source ss;
130 std::condition_variable_any cv;
131 Mutex mutex;
132 Lock lock{mutex};
134 std::atomic_bool start = false;
135 std::atomic_bool done = false;
136 auto thread = support::make_test_thread([&]() {
137 start.wait(false);
138 ss.request_stop();
140 while (!done) {
141 cv.notify_all();
142 std::this_thread::sleep_for(2ms);
146 std::same_as<bool> auto r = cv.wait_for(lock, ss.get_token(), 1h, [&]() {
147 start.store(true);
148 start.notify_all();
149 return false;
151 assert(!r);
152 done = true;
153 thread.join();
155 assert(lock.owns_lock());
158 #if !defined(TEST_HAS_NO_EXCEPTIONS)
159 // Throws: Any exception thrown by pred.
161 std::stop_source ss;
162 std::condition_variable_any cv;
163 Mutex mutex;
164 Lock lock{mutex};
166 try {
167 cv.wait_for(lock, ss.get_token(), 1h, []() -> bool { throw 5; });
168 assert(false);
169 } catch (int i) {
170 assert(i == 5);
173 #endif //!defined(TEST_HAS_NO_EXCEPTIONS)
176 int main(int, char**) {
177 test<std::mutex, std::unique_lock<std::mutex>>();
178 test<std::shared_mutex, std::shared_lock<std::shared_mutex>>();
180 return 0;