1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg//===---------------------- condition_variable ----------------------------===// 3*4d6fc14bSjoerg// 4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg// 8*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg 10*4d6fc14bSjoerg#ifndef _LIBCPP_CONDITION_VARIABLE 11*4d6fc14bSjoerg#define _LIBCPP_CONDITION_VARIABLE 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg/* 14*4d6fc14bSjoerg condition_variable synopsis 15*4d6fc14bSjoerg 16*4d6fc14bSjoergnamespace std 17*4d6fc14bSjoerg{ 18*4d6fc14bSjoerg 19*4d6fc14bSjoergenum class cv_status { no_timeout, timeout }; 20*4d6fc14bSjoerg 21*4d6fc14bSjoergclass condition_variable 22*4d6fc14bSjoerg{ 23*4d6fc14bSjoergpublic: 24*4d6fc14bSjoerg condition_variable(); 25*4d6fc14bSjoerg ~condition_variable(); 26*4d6fc14bSjoerg 27*4d6fc14bSjoerg condition_variable(const condition_variable&) = delete; 28*4d6fc14bSjoerg condition_variable& operator=(const condition_variable&) = delete; 29*4d6fc14bSjoerg 30*4d6fc14bSjoerg void notify_one() noexcept; 31*4d6fc14bSjoerg void notify_all() noexcept; 32*4d6fc14bSjoerg 33*4d6fc14bSjoerg void wait(unique_lock<mutex>& lock); 34*4d6fc14bSjoerg template <class Predicate> 35*4d6fc14bSjoerg void wait(unique_lock<mutex>& lock, Predicate pred); 36*4d6fc14bSjoerg 37*4d6fc14bSjoerg template <class Clock, class Duration> 38*4d6fc14bSjoerg cv_status 39*4d6fc14bSjoerg wait_until(unique_lock<mutex>& lock, 40*4d6fc14bSjoerg const chrono::time_point<Clock, Duration>& abs_time); 41*4d6fc14bSjoerg 42*4d6fc14bSjoerg template <class Clock, class Duration, class Predicate> 43*4d6fc14bSjoerg bool 44*4d6fc14bSjoerg wait_until(unique_lock<mutex>& lock, 45*4d6fc14bSjoerg const chrono::time_point<Clock, Duration>& abs_time, 46*4d6fc14bSjoerg Predicate pred); 47*4d6fc14bSjoerg 48*4d6fc14bSjoerg template <class Rep, class Period> 49*4d6fc14bSjoerg cv_status 50*4d6fc14bSjoerg wait_for(unique_lock<mutex>& lock, 51*4d6fc14bSjoerg const chrono::duration<Rep, Period>& rel_time); 52*4d6fc14bSjoerg 53*4d6fc14bSjoerg template <class Rep, class Period, class Predicate> 54*4d6fc14bSjoerg bool 55*4d6fc14bSjoerg wait_for(unique_lock<mutex>& lock, 56*4d6fc14bSjoerg const chrono::duration<Rep, Period>& rel_time, 57*4d6fc14bSjoerg Predicate pred); 58*4d6fc14bSjoerg 59*4d6fc14bSjoerg typedef pthread_cond_t* native_handle_type; 60*4d6fc14bSjoerg native_handle_type native_handle(); 61*4d6fc14bSjoerg}; 62*4d6fc14bSjoerg 63*4d6fc14bSjoergvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 64*4d6fc14bSjoerg 65*4d6fc14bSjoergclass condition_variable_any 66*4d6fc14bSjoerg{ 67*4d6fc14bSjoergpublic: 68*4d6fc14bSjoerg condition_variable_any(); 69*4d6fc14bSjoerg ~condition_variable_any(); 70*4d6fc14bSjoerg 71*4d6fc14bSjoerg condition_variable_any(const condition_variable_any&) = delete; 72*4d6fc14bSjoerg condition_variable_any& operator=(const condition_variable_any&) = delete; 73*4d6fc14bSjoerg 74*4d6fc14bSjoerg void notify_one() noexcept; 75*4d6fc14bSjoerg void notify_all() noexcept; 76*4d6fc14bSjoerg 77*4d6fc14bSjoerg template <class Lock> 78*4d6fc14bSjoerg void wait(Lock& lock); 79*4d6fc14bSjoerg template <class Lock, class Predicate> 80*4d6fc14bSjoerg void wait(Lock& lock, Predicate pred); 81*4d6fc14bSjoerg 82*4d6fc14bSjoerg template <class Lock, class Clock, class Duration> 83*4d6fc14bSjoerg cv_status 84*4d6fc14bSjoerg wait_until(Lock& lock, 85*4d6fc14bSjoerg const chrono::time_point<Clock, Duration>& abs_time); 86*4d6fc14bSjoerg 87*4d6fc14bSjoerg template <class Lock, class Clock, class Duration, class Predicate> 88*4d6fc14bSjoerg bool 89*4d6fc14bSjoerg wait_until(Lock& lock, 90*4d6fc14bSjoerg const chrono::time_point<Clock, Duration>& abs_time, 91*4d6fc14bSjoerg Predicate pred); 92*4d6fc14bSjoerg 93*4d6fc14bSjoerg template <class Lock, class Rep, class Period> 94*4d6fc14bSjoerg cv_status 95*4d6fc14bSjoerg wait_for(Lock& lock, 96*4d6fc14bSjoerg const chrono::duration<Rep, Period>& rel_time); 97*4d6fc14bSjoerg 98*4d6fc14bSjoerg template <class Lock, class Rep, class Period, class Predicate> 99*4d6fc14bSjoerg bool 100*4d6fc14bSjoerg wait_for(Lock& lock, 101*4d6fc14bSjoerg const chrono::duration<Rep, Period>& rel_time, 102*4d6fc14bSjoerg Predicate pred); 103*4d6fc14bSjoerg}; 104*4d6fc14bSjoerg 105*4d6fc14bSjoerg} // std 106*4d6fc14bSjoerg 107*4d6fc14bSjoerg*/ 108*4d6fc14bSjoerg 109*4d6fc14bSjoerg#include <__config> 110*4d6fc14bSjoerg#include <__mutex_base> 111*4d6fc14bSjoerg#include <memory> 112*4d6fc14bSjoerg 113*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 114*4d6fc14bSjoerg#pragma GCC system_header 115*4d6fc14bSjoerg#endif 116*4d6fc14bSjoerg 117*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_THREADS 118*4d6fc14bSjoerg 119*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD 120*4d6fc14bSjoerg 121*4d6fc14bSjoergclass _LIBCPP_TYPE_VIS condition_variable_any 122*4d6fc14bSjoerg{ 123*4d6fc14bSjoerg condition_variable __cv_; 124*4d6fc14bSjoerg shared_ptr<mutex> __mut_; 125*4d6fc14bSjoergpublic: 126*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 127*4d6fc14bSjoerg condition_variable_any(); 128*4d6fc14bSjoerg 129*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 130*4d6fc14bSjoerg void notify_one() _NOEXCEPT; 131*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 132*4d6fc14bSjoerg void notify_all() _NOEXCEPT; 133*4d6fc14bSjoerg 134*4d6fc14bSjoerg template <class _Lock> 135*4d6fc14bSjoerg _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 136*4d6fc14bSjoerg void wait(_Lock& __lock); 137*4d6fc14bSjoerg template <class _Lock, class _Predicate> 138*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 139*4d6fc14bSjoerg void wait(_Lock& __lock, _Predicate __pred); 140*4d6fc14bSjoerg 141*4d6fc14bSjoerg template <class _Lock, class _Clock, class _Duration> 142*4d6fc14bSjoerg _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 143*4d6fc14bSjoerg cv_status 144*4d6fc14bSjoerg wait_until(_Lock& __lock, 145*4d6fc14bSjoerg const chrono::time_point<_Clock, _Duration>& __t); 146*4d6fc14bSjoerg 147*4d6fc14bSjoerg template <class _Lock, class _Clock, class _Duration, class _Predicate> 148*4d6fc14bSjoerg bool 149*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 150*4d6fc14bSjoerg wait_until(_Lock& __lock, 151*4d6fc14bSjoerg const chrono::time_point<_Clock, _Duration>& __t, 152*4d6fc14bSjoerg _Predicate __pred); 153*4d6fc14bSjoerg 154*4d6fc14bSjoerg template <class _Lock, class _Rep, class _Period> 155*4d6fc14bSjoerg cv_status 156*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 157*4d6fc14bSjoerg wait_for(_Lock& __lock, 158*4d6fc14bSjoerg const chrono::duration<_Rep, _Period>& __d); 159*4d6fc14bSjoerg 160*4d6fc14bSjoerg template <class _Lock, class _Rep, class _Period, class _Predicate> 161*4d6fc14bSjoerg bool 162*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 163*4d6fc14bSjoerg wait_for(_Lock& __lock, 164*4d6fc14bSjoerg const chrono::duration<_Rep, _Period>& __d, 165*4d6fc14bSjoerg _Predicate __pred); 166*4d6fc14bSjoerg}; 167*4d6fc14bSjoerg 168*4d6fc14bSjoerginline 169*4d6fc14bSjoergcondition_variable_any::condition_variable_any() 170*4d6fc14bSjoerg : __mut_(make_shared<mutex>()) {} 171*4d6fc14bSjoerg 172*4d6fc14bSjoerginline 173*4d6fc14bSjoergvoid 174*4d6fc14bSjoergcondition_variable_any::notify_one() _NOEXCEPT 175*4d6fc14bSjoerg{ 176*4d6fc14bSjoerg {lock_guard<mutex> __lx(*__mut_);} 177*4d6fc14bSjoerg __cv_.notify_one(); 178*4d6fc14bSjoerg} 179*4d6fc14bSjoerg 180*4d6fc14bSjoerginline 181*4d6fc14bSjoergvoid 182*4d6fc14bSjoergcondition_variable_any::notify_all() _NOEXCEPT 183*4d6fc14bSjoerg{ 184*4d6fc14bSjoerg {lock_guard<mutex> __lx(*__mut_);} 185*4d6fc14bSjoerg __cv_.notify_all(); 186*4d6fc14bSjoerg} 187*4d6fc14bSjoerg 188*4d6fc14bSjoergstruct __lock_external 189*4d6fc14bSjoerg{ 190*4d6fc14bSjoerg template <class _Lock> 191*4d6fc14bSjoerg void operator()(_Lock* __m) {__m->lock();} 192*4d6fc14bSjoerg}; 193*4d6fc14bSjoerg 194*4d6fc14bSjoergtemplate <class _Lock> 195*4d6fc14bSjoergvoid 196*4d6fc14bSjoergcondition_variable_any::wait(_Lock& __lock) 197*4d6fc14bSjoerg{ 198*4d6fc14bSjoerg shared_ptr<mutex> __mut = __mut_; 199*4d6fc14bSjoerg unique_lock<mutex> __lk(*__mut); 200*4d6fc14bSjoerg __lock.unlock(); 201*4d6fc14bSjoerg unique_ptr<_Lock, __lock_external> __lxx(&__lock); 202*4d6fc14bSjoerg lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 203*4d6fc14bSjoerg __cv_.wait(__lk); 204*4d6fc14bSjoerg} // __mut_.unlock(), __lock.lock() 205*4d6fc14bSjoerg 206*4d6fc14bSjoergtemplate <class _Lock, class _Predicate> 207*4d6fc14bSjoerginline 208*4d6fc14bSjoergvoid 209*4d6fc14bSjoergcondition_variable_any::wait(_Lock& __lock, _Predicate __pred) 210*4d6fc14bSjoerg{ 211*4d6fc14bSjoerg while (!__pred()) 212*4d6fc14bSjoerg wait(__lock); 213*4d6fc14bSjoerg} 214*4d6fc14bSjoerg 215*4d6fc14bSjoergtemplate <class _Lock, class _Clock, class _Duration> 216*4d6fc14bSjoergcv_status 217*4d6fc14bSjoergcondition_variable_any::wait_until(_Lock& __lock, 218*4d6fc14bSjoerg const chrono::time_point<_Clock, _Duration>& __t) 219*4d6fc14bSjoerg{ 220*4d6fc14bSjoerg shared_ptr<mutex> __mut = __mut_; 221*4d6fc14bSjoerg unique_lock<mutex> __lk(*__mut); 222*4d6fc14bSjoerg __lock.unlock(); 223*4d6fc14bSjoerg unique_ptr<_Lock, __lock_external> __lxx(&__lock); 224*4d6fc14bSjoerg lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 225*4d6fc14bSjoerg return __cv_.wait_until(__lk, __t); 226*4d6fc14bSjoerg} // __mut_.unlock(), __lock.lock() 227*4d6fc14bSjoerg 228*4d6fc14bSjoergtemplate <class _Lock, class _Clock, class _Duration, class _Predicate> 229*4d6fc14bSjoerginline 230*4d6fc14bSjoergbool 231*4d6fc14bSjoergcondition_variable_any::wait_until(_Lock& __lock, 232*4d6fc14bSjoerg const chrono::time_point<_Clock, _Duration>& __t, 233*4d6fc14bSjoerg _Predicate __pred) 234*4d6fc14bSjoerg{ 235*4d6fc14bSjoerg while (!__pred()) 236*4d6fc14bSjoerg if (wait_until(__lock, __t) == cv_status::timeout) 237*4d6fc14bSjoerg return __pred(); 238*4d6fc14bSjoerg return true; 239*4d6fc14bSjoerg} 240*4d6fc14bSjoerg 241*4d6fc14bSjoergtemplate <class _Lock, class _Rep, class _Period> 242*4d6fc14bSjoerginline 243*4d6fc14bSjoergcv_status 244*4d6fc14bSjoergcondition_variable_any::wait_for(_Lock& __lock, 245*4d6fc14bSjoerg const chrono::duration<_Rep, _Period>& __d) 246*4d6fc14bSjoerg{ 247*4d6fc14bSjoerg return wait_until(__lock, chrono::steady_clock::now() + __d); 248*4d6fc14bSjoerg} 249*4d6fc14bSjoerg 250*4d6fc14bSjoergtemplate <class _Lock, class _Rep, class _Period, class _Predicate> 251*4d6fc14bSjoerginline 252*4d6fc14bSjoergbool 253*4d6fc14bSjoergcondition_variable_any::wait_for(_Lock& __lock, 254*4d6fc14bSjoerg const chrono::duration<_Rep, _Period>& __d, 255*4d6fc14bSjoerg _Predicate __pred) 256*4d6fc14bSjoerg{ 257*4d6fc14bSjoerg return wait_until(__lock, chrono::steady_clock::now() + __d, 258*4d6fc14bSjoerg _VSTD::move(__pred)); 259*4d6fc14bSjoerg} 260*4d6fc14bSjoerg 261*4d6fc14bSjoerg_LIBCPP_FUNC_VIS 262*4d6fc14bSjoergvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 263*4d6fc14bSjoerg 264*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD 265*4d6fc14bSjoerg 266*4d6fc14bSjoerg#endif // !_LIBCPP_HAS_NO_THREADS 267*4d6fc14bSjoerg 268*4d6fc14bSjoerg#endif // _LIBCPP_CONDITION_VARIABLE 269