29#ifndef _GLIBCXX_CONDITION_VARIABLE
30#define _GLIBCXX_CONDITION_VARIABLE 1
32#pragma GCC system_header
34#if __cplusplus < 201103L
43#include <bits/shared_ptr.h>
44#include <bits/cxxabi_forced.h>
46#if __cplusplus > 201703L
50#if defined(_GLIBCXX_HAS_GTHREADS)
52namespace std _GLIBCXX_VISIBILITY(default)
54_GLIBCXX_BEGIN_NAMESPACE_VERSION
72#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
81 typedef __gthread_cond_t* native_handle_type;
90 notify_one()
noexcept;
93 notify_all()
noexcept;
98 template<
typename _Predicate>
106#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
107 template<
typename _Duration>
111 {
return __wait_until_impl(__lock, __atime); }
114 template<
typename _Duration>
118 {
return __wait_until_impl(__lock, __atime); }
120 template<
typename _Clock,
typename _Duration>
125#if __cplusplus > 201703L
126 static_assert(chrono::is_clock_v<_Clock>);
128 using __s_dur =
typename __clock_t::duration;
129 const typename _Clock::time_point __c_entry = _Clock::now();
130 const __clock_t::time_point __s_entry = __clock_t::now();
131 const auto __delta = __atime - __c_entry;
132 const auto __s_atime = __s_entry +
133 chrono::__detail::ceil<__s_dur>(__delta);
135 if (__wait_until_impl(__lock, __s_atime) == cv_status::no_timeout)
136 return cv_status::no_timeout;
140 if (_Clock::now() < __atime)
141 return cv_status::no_timeout;
142 return cv_status::timeout;
145 template<
typename _Clock,
typename _Duration,
typename _Predicate>
152 if (wait_until(__lock, __atime) == cv_status::timeout)
157 template<
typename _Rep,
typename _Period>
162 using __dur =
typename steady_clock::duration;
163 return wait_until(__lock,
164 steady_clock::now() +
165 chrono::__detail::ceil<__dur>(__rtime));
168 template<
typename _Rep,
typename _Period,
typename _Predicate>
174 using __dur =
typename steady_clock::duration;
175 return wait_until(__lock,
176 steady_clock::now() +
177 chrono::__detail::ceil<__dur>(__rtime),
183 {
return _M_cond.native_handle(); }
186#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
187 template<
typename _Dur>
192 auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
193 auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
195 __gthread_time_t __ts =
197 static_cast<std::time_t
>(__s.time_since_epoch().count()),
198 static_cast<long>(__ns.count())
201 _M_cond.wait_until(*__lock.mutex(), CLOCK_MONOTONIC, __ts);
203 return (steady_clock::now() < __atime
204 ? cv_status::no_timeout : cv_status::timeout);
208 template<
typename _Dur>
213 auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
214 auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
216 __gthread_time_t __ts =
218 static_cast<std::time_t
>(__s.time_since_epoch().count()),
219 static_cast<long>(__ns.count())
222 _M_cond.wait_until(*__lock.mutex(), __ts);
224 return (system_clock::now() < __atime
225 ? cv_status::no_timeout : cv_status::timeout);
232 struct __at_thread_exit_elt
234 __at_thread_exit_elt* _M_next;
235 void (*_M_cb)(
void*);
238 inline namespace _V2 {
244#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
253 template<
typename _Lock>
256 explicit _Unlock(_Lock& __lk) : _M_lock(__lk) { __lk.unlock(); }
258#pragma GCC diagnostic push
259#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
260 ~_Unlock()
noexcept(
false)
267 { __throw_exception_again; }
274#pragma GCC diagnostic pop
276 _Unlock(
const _Unlock&) =
delete;
277 _Unlock& operator=(
const _Unlock&) =
delete;
290 notify_one()
noexcept
293 _M_cond.notify_one();
297 notify_all()
noexcept
300 _M_cond.notify_all();
303 template<
typename _Lock>
309 _Unlock<_Lock> __unlock(__lock);
313 _M_cond.wait(__my_lock2);
317 template<
typename _Lock,
typename _Predicate>
319 wait(_Lock& __lock, _Predicate __p)
325 template<
typename _Lock,
typename _Clock,
typename _Duration>
327 wait_until(_Lock& __lock,
332 _Unlock<_Lock> __unlock(__lock);
336 return _M_cond.wait_until(__my_lock2, __atime);
339 template<
typename _Lock,
typename _Clock,
340 typename _Duration,
typename _Predicate>
342 wait_until(_Lock& __lock,
347 if (wait_until(__lock, __atime) == cv_status::timeout)
352 template<
typename _Lock,
typename _Rep,
typename _Period>
355 {
return wait_until(__lock, __clock_t::now() + __rtime); }
357 template<
typename _Lock,
typename _Rep,
358 typename _Period,
typename _Predicate>
360 wait_for(_Lock& __lock,
362 {
return wait_until(__lock, __clock_t::now() + __rtime,
std::move(__p)); }
364#ifdef __cpp_lib_jthread
365 template <
class _Lock,
class _Predicate>
366 bool wait(_Lock& __lock,
370 if (__stoken.stop_requested())
375 std::stop_callback __cb(__stoken, [
this] { notify_all(); });
380 if (__stoken.stop_requested())
386 _Unlock<_Lock> __unlock(__lock);
388 _M_cond.wait(__my_lock2);
393 template <
class _Lock,
class _Clock,
class _Duration,
class _Predicate>
394 bool wait_until(_Lock& __lock,
399 if (__stoken.stop_requested())
404 std::stop_callback __cb(__stoken, [
this] { notify_all(); });
411 if (__stoken.stop_requested())
415 _Unlock<_Lock> __u(__lock);
417 const auto __status = _M_cond.wait_until(__my_lock2, __abs_time);
418 __stop = (__status == std::cv_status::timeout) || __stoken.stop_requested();
428 template <
class _Lock,
class _Rep,
class _Period,
class _Predicate>
429 bool wait_for(_Lock& __lock,
434 auto __abst = std::chrono::steady_clock::now() + __rel_time;
435 return wait_until(__lock,
446_GLIBCXX_END_NAMESPACE_VERSION
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
bool uncaught_exception() noexcept
ISO C++ entities toplevel namespace is std.
chrono::duration represents a distance between two points in time
chrono::time_point represents a point in time as measured by a clock
A smart pointer with reference-counted copy semantics.
A simple scoped lock type.
A movable scoped lock type.
Thrown as part of forced unwinding.