146035553Spatrick// -*- C++ -*- 2*4bdff4beSrobert//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP_CONDITION_VARIABLE 1146035553Spatrick#define _LIBCPP_CONDITION_VARIABLE 1246035553Spatrick 1346035553Spatrick/* 1446035553Spatrick condition_variable synopsis 1546035553Spatrick 1646035553Spatricknamespace std 1746035553Spatrick{ 1846035553Spatrick 1946035553Spatrickenum class cv_status { no_timeout, timeout }; 2046035553Spatrick 2146035553Spatrickclass condition_variable 2246035553Spatrick{ 2346035553Spatrickpublic: 2446035553Spatrick condition_variable(); 2546035553Spatrick ~condition_variable(); 2646035553Spatrick 2746035553Spatrick condition_variable(const condition_variable&) = delete; 2846035553Spatrick condition_variable& operator=(const condition_variable&) = delete; 2946035553Spatrick 3046035553Spatrick void notify_one() noexcept; 3146035553Spatrick void notify_all() noexcept; 3246035553Spatrick 3346035553Spatrick void wait(unique_lock<mutex>& lock); 3446035553Spatrick template <class Predicate> 3546035553Spatrick void wait(unique_lock<mutex>& lock, Predicate pred); 3646035553Spatrick 3746035553Spatrick template <class Clock, class Duration> 3846035553Spatrick cv_status 3946035553Spatrick wait_until(unique_lock<mutex>& lock, 4046035553Spatrick const chrono::time_point<Clock, Duration>& abs_time); 4146035553Spatrick 4246035553Spatrick template <class Clock, class Duration, class Predicate> 4346035553Spatrick bool 4446035553Spatrick wait_until(unique_lock<mutex>& lock, 4546035553Spatrick const chrono::time_point<Clock, Duration>& abs_time, 4646035553Spatrick Predicate pred); 4746035553Spatrick 4846035553Spatrick template <class Rep, class Period> 4946035553Spatrick cv_status 5046035553Spatrick wait_for(unique_lock<mutex>& lock, 5146035553Spatrick const chrono::duration<Rep, Period>& rel_time); 5246035553Spatrick 5346035553Spatrick template <class Rep, class Period, class Predicate> 5446035553Spatrick bool 5546035553Spatrick wait_for(unique_lock<mutex>& lock, 5646035553Spatrick const chrono::duration<Rep, Period>& rel_time, 5746035553Spatrick Predicate pred); 5846035553Spatrick 5946035553Spatrick typedef pthread_cond_t* native_handle_type; 6046035553Spatrick native_handle_type native_handle(); 6146035553Spatrick}; 6246035553Spatrick 6346035553Spatrickvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 6446035553Spatrick 6546035553Spatrickclass condition_variable_any 6646035553Spatrick{ 6746035553Spatrickpublic: 6846035553Spatrick condition_variable_any(); 6946035553Spatrick ~condition_variable_any(); 7046035553Spatrick 7146035553Spatrick condition_variable_any(const condition_variable_any&) = delete; 7246035553Spatrick condition_variable_any& operator=(const condition_variable_any&) = delete; 7346035553Spatrick 7446035553Spatrick void notify_one() noexcept; 7546035553Spatrick void notify_all() noexcept; 7646035553Spatrick 7746035553Spatrick template <class Lock> 7846035553Spatrick void wait(Lock& lock); 7946035553Spatrick template <class Lock, class Predicate> 8046035553Spatrick void wait(Lock& lock, Predicate pred); 8146035553Spatrick 8246035553Spatrick template <class Lock, class Clock, class Duration> 8346035553Spatrick cv_status 8446035553Spatrick wait_until(Lock& lock, 8546035553Spatrick const chrono::time_point<Clock, Duration>& abs_time); 8646035553Spatrick 8746035553Spatrick template <class Lock, class Clock, class Duration, class Predicate> 8846035553Spatrick bool 8946035553Spatrick wait_until(Lock& lock, 9046035553Spatrick const chrono::time_point<Clock, Duration>& abs_time, 9146035553Spatrick Predicate pred); 9246035553Spatrick 9346035553Spatrick template <class Lock, class Rep, class Period> 9446035553Spatrick cv_status 9546035553Spatrick wait_for(Lock& lock, 9646035553Spatrick const chrono::duration<Rep, Period>& rel_time); 9746035553Spatrick 9846035553Spatrick template <class Lock, class Rep, class Period, class Predicate> 9946035553Spatrick bool 10046035553Spatrick wait_for(Lock& lock, 10146035553Spatrick const chrono::duration<Rep, Period>& rel_time, 10246035553Spatrick Predicate pred); 10346035553Spatrick}; 10446035553Spatrick 10546035553Spatrick} // std 10646035553Spatrick 10746035553Spatrick*/ 10846035553Spatrick 109*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 11046035553Spatrick#include <__config> 111*4bdff4beSrobert#include <__memory/shared_ptr.h> 112*4bdff4beSrobert#include <__memory/unique_ptr.h> 11346035553Spatrick#include <__mutex_base> 114*4bdff4beSrobert#include <version> 11546035553Spatrick 11646035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 11746035553Spatrick# pragma GCC system_header 11846035553Spatrick#endif 11946035553Spatrick 12046035553Spatrick#ifndef _LIBCPP_HAS_NO_THREADS 12146035553Spatrick 12246035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 12346035553Spatrick 12446035553Spatrickclass _LIBCPP_TYPE_VIS condition_variable_any 12546035553Spatrick{ 12646035553Spatrick condition_variable __cv_; 12746035553Spatrick shared_ptr<mutex> __mut_; 12846035553Spatrickpublic: 12946035553Spatrick _LIBCPP_INLINE_VISIBILITY 13046035553Spatrick condition_variable_any(); 13146035553Spatrick 13246035553Spatrick _LIBCPP_INLINE_VISIBILITY 13346035553Spatrick void notify_one() _NOEXCEPT; 13446035553Spatrick _LIBCPP_INLINE_VISIBILITY 13546035553Spatrick void notify_all() _NOEXCEPT; 13646035553Spatrick 13746035553Spatrick template <class _Lock> 13846035553Spatrick _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 13946035553Spatrick void wait(_Lock& __lock); 14046035553Spatrick template <class _Lock, class _Predicate> 14146035553Spatrick _LIBCPP_INLINE_VISIBILITY 14246035553Spatrick void wait(_Lock& __lock, _Predicate __pred); 14346035553Spatrick 14446035553Spatrick template <class _Lock, class _Clock, class _Duration> 14546035553Spatrick _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 14646035553Spatrick cv_status 14746035553Spatrick wait_until(_Lock& __lock, 14846035553Spatrick const chrono::time_point<_Clock, _Duration>& __t); 14946035553Spatrick 15046035553Spatrick template <class _Lock, class _Clock, class _Duration, class _Predicate> 15146035553Spatrick bool 15246035553Spatrick _LIBCPP_INLINE_VISIBILITY 15346035553Spatrick wait_until(_Lock& __lock, 15446035553Spatrick const chrono::time_point<_Clock, _Duration>& __t, 15546035553Spatrick _Predicate __pred); 15646035553Spatrick 15746035553Spatrick template <class _Lock, class _Rep, class _Period> 15846035553Spatrick cv_status 15946035553Spatrick _LIBCPP_INLINE_VISIBILITY 16046035553Spatrick wait_for(_Lock& __lock, 16146035553Spatrick const chrono::duration<_Rep, _Period>& __d); 16246035553Spatrick 16346035553Spatrick template <class _Lock, class _Rep, class _Period, class _Predicate> 16446035553Spatrick bool 16546035553Spatrick _LIBCPP_INLINE_VISIBILITY 16646035553Spatrick wait_for(_Lock& __lock, 16746035553Spatrick const chrono::duration<_Rep, _Period>& __d, 16846035553Spatrick _Predicate __pred); 16946035553Spatrick}; 17046035553Spatrick 17146035553Spatrickinline 17246035553Spatrickcondition_variable_any::condition_variable_any() 17346035553Spatrick : __mut_(make_shared<mutex>()) {} 17446035553Spatrick 17546035553Spatrickinline 17646035553Spatrickvoid 17746035553Spatrickcondition_variable_any::notify_one() _NOEXCEPT 17846035553Spatrick{ 17946035553Spatrick {lock_guard<mutex> __lx(*__mut_);} 18046035553Spatrick __cv_.notify_one(); 18146035553Spatrick} 18246035553Spatrick 18346035553Spatrickinline 18446035553Spatrickvoid 18546035553Spatrickcondition_variable_any::notify_all() _NOEXCEPT 18646035553Spatrick{ 18746035553Spatrick {lock_guard<mutex> __lx(*__mut_);} 18846035553Spatrick __cv_.notify_all(); 18946035553Spatrick} 19046035553Spatrick 19146035553Spatrickstruct __lock_external 19246035553Spatrick{ 19346035553Spatrick template <class _Lock> 19446035553Spatrick void operator()(_Lock* __m) {__m->lock();} 19546035553Spatrick}; 19646035553Spatrick 19746035553Spatricktemplate <class _Lock> 19846035553Spatrickvoid 19946035553Spatrickcondition_variable_any::wait(_Lock& __lock) 20046035553Spatrick{ 20146035553Spatrick shared_ptr<mutex> __mut = __mut_; 20246035553Spatrick unique_lock<mutex> __lk(*__mut); 20346035553Spatrick __lock.unlock(); 20446035553Spatrick unique_ptr<_Lock, __lock_external> __lxx(&__lock); 20546035553Spatrick lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 20646035553Spatrick __cv_.wait(__lk); 20746035553Spatrick} // __mut_.unlock(), __lock.lock() 20846035553Spatrick 20946035553Spatricktemplate <class _Lock, class _Predicate> 21046035553Spatrickinline 21146035553Spatrickvoid 21246035553Spatrickcondition_variable_any::wait(_Lock& __lock, _Predicate __pred) 21346035553Spatrick{ 21446035553Spatrick while (!__pred()) 21546035553Spatrick wait(__lock); 21646035553Spatrick} 21746035553Spatrick 21846035553Spatricktemplate <class _Lock, class _Clock, class _Duration> 21946035553Spatrickcv_status 22046035553Spatrickcondition_variable_any::wait_until(_Lock& __lock, 22146035553Spatrick const chrono::time_point<_Clock, _Duration>& __t) 22246035553Spatrick{ 22346035553Spatrick shared_ptr<mutex> __mut = __mut_; 22446035553Spatrick unique_lock<mutex> __lk(*__mut); 22546035553Spatrick __lock.unlock(); 22646035553Spatrick unique_ptr<_Lock, __lock_external> __lxx(&__lock); 22746035553Spatrick lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 22846035553Spatrick return __cv_.wait_until(__lk, __t); 22946035553Spatrick} // __mut_.unlock(), __lock.lock() 23046035553Spatrick 23146035553Spatricktemplate <class _Lock, class _Clock, class _Duration, class _Predicate> 23246035553Spatrickinline 23346035553Spatrickbool 23446035553Spatrickcondition_variable_any::wait_until(_Lock& __lock, 23546035553Spatrick const chrono::time_point<_Clock, _Duration>& __t, 23646035553Spatrick _Predicate __pred) 23746035553Spatrick{ 23846035553Spatrick while (!__pred()) 23946035553Spatrick if (wait_until(__lock, __t) == cv_status::timeout) 24046035553Spatrick return __pred(); 24146035553Spatrick return true; 24246035553Spatrick} 24346035553Spatrick 24446035553Spatricktemplate <class _Lock, class _Rep, class _Period> 24546035553Spatrickinline 24646035553Spatrickcv_status 24746035553Spatrickcondition_variable_any::wait_for(_Lock& __lock, 24846035553Spatrick const chrono::duration<_Rep, _Period>& __d) 24946035553Spatrick{ 25046035553Spatrick return wait_until(__lock, chrono::steady_clock::now() + __d); 25146035553Spatrick} 25246035553Spatrick 25346035553Spatricktemplate <class _Lock, class _Rep, class _Period, class _Predicate> 25446035553Spatrickinline 25546035553Spatrickbool 25646035553Spatrickcondition_variable_any::wait_for(_Lock& __lock, 25746035553Spatrick const chrono::duration<_Rep, _Period>& __d, 25846035553Spatrick _Predicate __pred) 25946035553Spatrick{ 26046035553Spatrick return wait_until(__lock, chrono::steady_clock::now() + __d, 26146035553Spatrick _VSTD::move(__pred)); 26246035553Spatrick} 26346035553Spatrick 26446035553Spatrick_LIBCPP_FUNC_VIS 265*4bdff4beSrobertvoid notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>); 26646035553Spatrick 26746035553Spatrick_LIBCPP_END_NAMESPACE_STD 26846035553Spatrick 26946035553Spatrick#endif // !_LIBCPP_HAS_NO_THREADS 27046035553Spatrick 271*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 272*4bdff4beSrobert# include <concepts> 273*4bdff4beSrobert# include <type_traits> 274*4bdff4beSrobert#endif 275*4bdff4beSrobert 27646035553Spatrick#endif // _LIBCPP_CONDITION_VARIABLE 277