Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / condition_variable
blobeb1c4bf5de6b6d8c62054ae3071df3de39ecf85a
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_CONDITION_VARIABLE
11 #define _LIBCPP_CONDITION_VARIABLE
14     condition_variable synopsis
16 namespace std
19 enum class cv_status { no_timeout, timeout };
21 class condition_variable
23 public:
24     condition_variable();
25     ~condition_variable();
27     condition_variable(const condition_variable&) = delete;
28     condition_variable& operator=(const condition_variable&) = delete;
30     void notify_one() noexcept;
31     void notify_all() noexcept;
33     void wait(unique_lock<mutex>& lock);
34     template <class Predicate>
35         void wait(unique_lock<mutex>& lock, Predicate pred);
37     template <class Clock, class Duration>
38         cv_status
39         wait_until(unique_lock<mutex>& lock,
40                    const chrono::time_point<Clock, Duration>& abs_time);
42     template <class Clock, class Duration, class Predicate>
43         bool
44         wait_until(unique_lock<mutex>& lock,
45                    const chrono::time_point<Clock, Duration>& abs_time,
46                    Predicate pred);
48     template <class Rep, class Period>
49         cv_status
50         wait_for(unique_lock<mutex>& lock,
51                  const chrono::duration<Rep, Period>& rel_time);
53     template <class Rep, class Period, class Predicate>
54         bool
55         wait_for(unique_lock<mutex>& lock,
56                  const chrono::duration<Rep, Period>& rel_time,
57                  Predicate pred);
59     typedef pthread_cond_t* native_handle_type;
60     native_handle_type native_handle();
63 void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
65 class condition_variable_any
67 public:
68     condition_variable_any();
69     ~condition_variable_any();
71     condition_variable_any(const condition_variable_any&) = delete;
72     condition_variable_any& operator=(const condition_variable_any&) = delete;
74     void notify_one() noexcept;
75     void notify_all() noexcept;
77     template <class Lock>
78         void wait(Lock& lock);
79     template <class Lock, class Predicate>
80         void wait(Lock& lock, Predicate pred);
82     template <class Lock, class Clock, class Duration>
83         cv_status
84         wait_until(Lock& lock,
85                    const chrono::time_point<Clock, Duration>& abs_time);
87     template <class Lock, class Clock, class Duration, class Predicate>
88         bool
89         wait_until(Lock& lock,
90                    const chrono::time_point<Clock, Duration>& abs_time,
91                    Predicate pred);
93     template <class Lock, class Rep, class Period>
94         cv_status
95         wait_for(Lock& lock,
96                  const chrono::duration<Rep, Period>& rel_time);
98     template <class Lock, class Rep, class Period, class Predicate>
99         bool
100         wait_for(Lock& lock,
101                  const chrono::duration<Rep, Period>& rel_time,
102                  Predicate pred);
104     // [thread.condvarany.intwait], interruptible waits
105     template <class Lock, class Predicate>
106       bool wait(Lock& lock, stop_token stoken, Predicate pred);                               // since C++20
108     template <class Lock, class Clock, class Duration, class Predicate>
109       bool wait_until(Lock& lock, stop_token stoken,
110                       const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);   // since C++20
112     template <class Lock, class Rep, class Period, class Predicate>
113       bool wait_for(Lock& lock, stop_token stoken,
114                     const chrono::duration<Rep, Period>& rel_time, Predicate pred);           // since C++20
117 }  // std
121 #include <__assert> // all public C++ headers provide the assertion handler
122 #include <__availability>
123 #include <__chrono/duration.h>
124 #include <__chrono/steady_clock.h>
125 #include <__chrono/time_point.h>
126 #include <__condition_variable/condition_variable.h>
127 #include <__config>
128 #include <__memory/shared_ptr.h>
129 #include <__memory/unique_ptr.h>
130 #include <__mutex/lock_guard.h>
131 #include <__mutex/mutex.h>
132 #include <__mutex/tag_types.h>
133 #include <__mutex/unique_lock.h>
134 #include <__stop_token/stop_token.h>
135 #include <__utility/move.h>
136 #include <version>
138 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
139 #  pragma GCC system_header
140 #endif
142 #ifndef _LIBCPP_HAS_NO_THREADS
144 _LIBCPP_BEGIN_NAMESPACE_STD
146 class _LIBCPP_EXPORTED_FROM_ABI condition_variable_any
148     condition_variable __cv_;
149     shared_ptr<mutex>  __mut_;
150 public:
151     _LIBCPP_INLINE_VISIBILITY
152     condition_variable_any();
154     _LIBCPP_INLINE_VISIBILITY
155     void notify_one() _NOEXCEPT;
156     _LIBCPP_INLINE_VISIBILITY
157     void notify_all() _NOEXCEPT;
159     template <class _Lock>
160         _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
161         void wait(_Lock& __lock);
162     template <class _Lock, class _Predicate>
163         _LIBCPP_INLINE_VISIBILITY
164         void wait(_Lock& __lock, _Predicate __pred);
166     template <class _Lock, class _Clock, class _Duration>
167         _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
168         cv_status
169         wait_until(_Lock& __lock,
170                    const chrono::time_point<_Clock, _Duration>& __t);
172     template <class _Lock, class _Clock, class _Duration, class _Predicate>
173         bool
174         _LIBCPP_INLINE_VISIBILITY
175         wait_until(_Lock& __lock,
176                    const chrono::time_point<_Clock, _Duration>& __t,
177                    _Predicate __pred);
179     template <class _Lock, class _Rep, class _Period>
180         cv_status
181         _LIBCPP_INLINE_VISIBILITY
182         wait_for(_Lock& __lock,
183                  const chrono::duration<_Rep, _Period>& __d);
185     template <class _Lock, class _Rep, class _Period, class _Predicate>
186         bool
187         _LIBCPP_INLINE_VISIBILITY
188         wait_for(_Lock& __lock,
189                  const chrono::duration<_Rep, _Period>& __d,
190                  _Predicate __pred);
192 #if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
194     template <class _Lock, class _Predicate>
195     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool wait(_Lock& __lock, stop_token __stoken, _Predicate __pred);
197     template <class _Lock, class _Clock, class _Duration, class _Predicate>
198     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool wait_until(_Lock& __lock, stop_token __stoken,
199                 const chrono::time_point<_Clock, _Duration>& __abs_time, _Predicate __pred);
201     template <class _Lock, class _Rep, class _Period, class _Predicate>
202     _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool wait_for(_Lock& __lock, stop_token __stoken,
203                 const chrono::duration<_Rep, _Period>& __rel_time, _Predicate __pred);
205 #endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
208 inline
209 condition_variable_any::condition_variable_any()
210     : __mut_(make_shared<mutex>()) {}
212 inline
213 void
214 condition_variable_any::notify_one() _NOEXCEPT
216     {lock_guard<mutex> __lx(*__mut_);}
217     __cv_.notify_one();
220 inline
221 void
222 condition_variable_any::notify_all() _NOEXCEPT
224     {lock_guard<mutex> __lx(*__mut_);}
225     __cv_.notify_all();
228 struct __lock_external
230     template <class _Lock>
231     _LIBCPP_HIDE_FROM_ABI void operator()(_Lock* __m) {__m->lock();}
234 template <class _Lock>
235 void
236 condition_variable_any::wait(_Lock& __lock)
238     shared_ptr<mutex> __mut = __mut_;
239     unique_lock<mutex> __lk(*__mut);
240     __lock.unlock();
241     unique_ptr<_Lock, __lock_external> __lxx(&__lock);
242     lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
243     __cv_.wait(__lk);
244 }  // __mut_.unlock(), __lock.lock()
246 template <class _Lock, class _Predicate>
247 inline
248 void
249 condition_variable_any::wait(_Lock& __lock, _Predicate __pred)
251     while (!__pred())
252         wait(__lock);
255 template <class _Lock, class _Clock, class _Duration>
256 cv_status
257 condition_variable_any::wait_until(_Lock& __lock,
258                                    const chrono::time_point<_Clock, _Duration>& __t)
260     shared_ptr<mutex> __mut = __mut_;
261     unique_lock<mutex> __lk(*__mut);
262     __lock.unlock();
263     unique_ptr<_Lock, __lock_external> __lxx(&__lock);
264     lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
265     return __cv_.wait_until(__lk, __t);
266 }  // __mut_.unlock(), __lock.lock()
268 template <class _Lock, class _Clock, class _Duration, class _Predicate>
269 inline
270 bool
271 condition_variable_any::wait_until(_Lock& __lock,
272                                    const chrono::time_point<_Clock, _Duration>& __t,
273                                    _Predicate __pred)
275     while (!__pred())
276         if (wait_until(__lock, __t) == cv_status::timeout)
277             return __pred();
278     return true;
281 template <class _Lock, class _Rep, class _Period>
282 inline
283 cv_status
284 condition_variable_any::wait_for(_Lock& __lock,
285                                  const chrono::duration<_Rep, _Period>& __d)
287     return wait_until(__lock, chrono::steady_clock::now() + __d);
290 template <class _Lock, class _Rep, class _Period, class _Predicate>
291 inline
292 bool
293 condition_variable_any::wait_for(_Lock& __lock,
294                                  const chrono::duration<_Rep, _Period>& __d,
295                                  _Predicate __pred)
297     return wait_until(__lock, chrono::steady_clock::now() + __d,
298                       _VSTD::move(__pred));
301 #if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
303 template <class _Lock, class _Predicate>
304 bool condition_variable_any::wait(_Lock& __lock, stop_token __stoken, _Predicate __pred) {
305     while (!__stoken.stop_requested()) {
306         if (__pred())
307             return true;
308         wait(__lock);
309     }
310     return __pred();
313 template <class _Lock, class _Clock, class _Duration, class _Predicate>
314 bool condition_variable_any::wait_until(
315     _Lock& __lock, stop_token __stoken, const chrono::time_point<_Clock, _Duration>& __abs_time, _Predicate __pred) {
316     while (!__stoken.stop_requested()) {
317         if (__pred())
318             return true;
319         if (wait_until(__lock, __abs_time) == cv_status::timeout)
320             return __pred();
321     }
322     return __pred();
325 template <class _Lock, class _Rep, class _Period, class _Predicate>
326 bool condition_variable_any::wait_for(
327     _Lock& __lock, stop_token __stoken, const chrono::duration<_Rep, _Period>& __rel_time, _Predicate __pred) {
328     return wait_until(__lock, std::move(__stoken), chrono::steady_clock::now() + __rel_time, std::move(__pred));
331 #endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
333 _LIBCPP_EXPORTED_FROM_ABI void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>);
335 _LIBCPP_END_NAMESPACE_STD
337 #endif // !_LIBCPP_HAS_NO_THREADS
339 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
340 #  include <atomic>
341 #  include <concepts>
342 #  include <cstdint>
343 #  include <cstdlib>
344 #  include <cstring>
345 #  include <initializer_list>
346 #  include <iosfwd>
347 #  include <new>
348 #  include <stdexcept>
349 #  include <system_error>
350 #  include <type_traits>
351 #  include <typeinfo>
352 #endif
354 #endif // _LIBCPP_CONDITION_VARIABLE