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>
46 #if __cplusplus > 201703L
50 #if defined(_GLIBCXX_HAS_GTHREADS)
52 namespace std _GLIBCXX_VISIBILITY(default)
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
70 using steady_clock = chrono::steady_clock;
71 using system_clock = chrono::system_clock;
72 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
73 using __clock_t = steady_clock;
75 using __clock_t = system_clock;
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>
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>
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
245 using __clock_t = chrono::steady_clock;
247 using __clock_t = chrono::system_clock;
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
449 #endif // _GLIBCXX_HAS_GTHREADS
451 #endif // _GLIBCXX_CONDITION_VARIABLE
constexpr enable_if< __is_duration< _ToDur >::value, time_point< _Clock, _ToDur > >::type time_point_cast(const time_point< _Clock, _Dur > &__t)
time_point_cast
Thrown as part of forced unwinding.A magic placeholder class that can be caught by reference to recog...
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
A smart pointer with reference-counted copy semantics.
A simple scoped lock type.
bool uncaught_exception() noexcept
A movable scoped lock type.
constexpr __enable_if_is_duration< _ToDur > duration_cast(const duration< _Rep, _Period > &__d)
duration_cast
auto_ptr & operator=(auto_ptr &__a)
auto_ptr assignment operator.