17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===----------------------------------------------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP___MUTEX_BASE 127a984708SDavid Chisnall#define _LIBCPP___MUTEX_BASE 137a984708SDavid Chisnall 147a984708SDavid Chisnall#include <__config> 157a984708SDavid Chisnall#include <chrono> 167a984708SDavid Chisnall#include <system_error> 177c82a1ecSDimitry Andric#include <__threading_support> 18f9448bf3SDimitry Andric 197a984708SDavid Chisnall 207a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 217a984708SDavid Chisnall#pragma GCC system_header 227a984708SDavid Chisnall#endif 237a984708SDavid Chisnall 24f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS 25f9448bf3SDimitry Andric#include <__undef_macros> 26f9448bf3SDimitry Andric 27f9448bf3SDimitry Andric 287a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 297a984708SDavid Chisnall 30d72607e9SDimitry Andric#ifndef _LIBCPP_HAS_NO_THREADS 31d72607e9SDimitry Andric 327c82a1ecSDimitry Andric#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION 337c82a1ecSDimitry Andric# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS 347c82a1ecSDimitry Andric# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x)) 357c82a1ecSDimitry Andric# else 367c82a1ecSDimitry Andric# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) 377c82a1ecSDimitry Andric# endif 387c82a1ecSDimitry Andric#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION 397c82a1ecSDimitry Andric 407c82a1ecSDimitry Andricclass _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex 417a984708SDavid Chisnall{ 42540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 437c82a1ecSDimitry Andric __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; 447c82a1ecSDimitry Andric#else 457c82a1ecSDimitry Andric __libcpp_mutex_t __m_; 467c82a1ecSDimitry Andric#endif 477a984708SDavid Chisnall 487a984708SDavid Chisnallpublic: 497a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 50540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 51db17bf38SDimitry Andric constexpr mutex() = default; 52936e9439SDimitry Andric#else 537c82a1ecSDimitry Andric mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;} 54936e9439SDimitry Andric#endif 557a984708SDavid Chisnall ~mutex(); 567a984708SDavid Chisnall 577a984708SDavid Chisnallprivate: 587a984708SDavid Chisnall mutex(const mutex&);// = delete; 597a984708SDavid Chisnall mutex& operator=(const mutex&);// = delete; 607a984708SDavid Chisnall 617a984708SDavid Chisnallpublic: 627c82a1ecSDimitry Andric void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); 637c82a1ecSDimitry Andric bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); 647c82a1ecSDimitry Andric void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); 657a984708SDavid Chisnall 667c82a1ecSDimitry Andric typedef __libcpp_mutex_t* native_handle_type; 677a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} 687a984708SDavid Chisnall}; 697a984708SDavid Chisnall 70db17bf38SDimitry Andricstatic_assert(is_nothrow_default_constructible<mutex>::value, 71db17bf38SDimitry Andric "the default constructor for std::mutex must be nothrow"); 72db17bf38SDimitry Andric 731bf9f7c1SDimitry Andricstruct _LIBCPP_TYPE_VIS defer_lock_t {}; 741bf9f7c1SDimitry Andricstruct _LIBCPP_TYPE_VIS try_to_lock_t {}; 751bf9f7c1SDimitry Andricstruct _LIBCPP_TYPE_VIS adopt_lock_t {}; 767a984708SDavid Chisnall 774ba319b5SDimitry Andric#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) 787a984708SDavid Chisnall 79*b5893f02SDimitry Andricextern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock; 80*b5893f02SDimitry Andricextern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock; 81*b5893f02SDimitry Andricextern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock; 827a984708SDavid Chisnall 83936e9439SDimitry Andric#else 84936e9439SDimitry Andric 8530785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr defer_lock_t defer_lock = defer_lock_t(); 8630785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr try_to_lock_t try_to_lock = try_to_lock_t(); 8730785c0eSDimitry Andric/* _LIBCPP_INLINE_VAR */ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); 88936e9439SDimitry Andric 89936e9439SDimitry Andric#endif 907a984708SDavid Chisnall 917a984708SDavid Chisnalltemplate <class _Mutex> 92aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) 937c82a1ecSDimitry Andriclock_guard 947a984708SDavid Chisnall{ 957a984708SDavid Chisnallpublic: 967a984708SDavid Chisnall typedef _Mutex mutex_type; 977a984708SDavid Chisnall 987a984708SDavid Chisnallprivate: 997a984708SDavid Chisnall mutex_type& __m_; 1007a984708SDavid Chisnallpublic: 1017a984708SDavid Chisnall 1027a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1037c82a1ecSDimitry Andric explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) 1047a984708SDavid Chisnall : __m_(__m) {__m_.lock();} 1057a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1067c82a1ecSDimitry Andric lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) 1077a984708SDavid Chisnall : __m_(__m) {} 1087a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1097c82a1ecSDimitry Andric ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();} 1107a984708SDavid Chisnall 1117a984708SDavid Chisnallprivate: 1127c82a1ecSDimitry Andric lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE; 1137c82a1ecSDimitry Andric lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE; 1147a984708SDavid Chisnall}; 1157a984708SDavid Chisnall 1167a984708SDavid Chisnalltemplate <class _Mutex> 117aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS unique_lock 1187a984708SDavid Chisnall{ 1197a984708SDavid Chisnallpublic: 1207a984708SDavid Chisnall typedef _Mutex mutex_type; 1217a984708SDavid Chisnall 1227a984708SDavid Chisnallprivate: 1237a984708SDavid Chisnall mutex_type* __m_; 1247a984708SDavid Chisnall bool __owns_; 1257a984708SDavid Chisnall 1267a984708SDavid Chisnallpublic: 1277a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 128936e9439SDimitry Andric unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} 1297a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1307a984708SDavid Chisnall explicit unique_lock(mutex_type& __m) 1317c82a1ecSDimitry Andric : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();} 1327a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 133936e9439SDimitry Andric unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT 1347c82a1ecSDimitry Andric : __m_(_VSTD::addressof(__m)), __owns_(false) {} 1357a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1367a984708SDavid Chisnall unique_lock(mutex_type& __m, try_to_lock_t) 1377c82a1ecSDimitry Andric : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {} 1387a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1397a984708SDavid Chisnall unique_lock(mutex_type& __m, adopt_lock_t) 1407c82a1ecSDimitry Andric : __m_(_VSTD::addressof(__m)), __owns_(true) {} 1417a984708SDavid Chisnall template <class _Clock, class _Duration> 1427a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1437a984708SDavid Chisnall unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) 1447c82a1ecSDimitry Andric : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {} 1457a984708SDavid Chisnall template <class _Rep, class _Period> 1467a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1477a984708SDavid Chisnall unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) 1487c82a1ecSDimitry Andric : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {} 1497a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1507a984708SDavid Chisnall ~unique_lock() 1517a984708SDavid Chisnall { 1527a984708SDavid Chisnall if (__owns_) 1537a984708SDavid Chisnall __m_->unlock(); 1547a984708SDavid Chisnall } 1557a984708SDavid Chisnall 1567a984708SDavid Chisnallprivate: 1577a984708SDavid Chisnall unique_lock(unique_lock const&); // = delete; 1587a984708SDavid Chisnall unique_lock& operator=(unique_lock const&); // = delete; 1597a984708SDavid Chisnall 1607a984708SDavid Chisnallpublic: 161540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1627a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 163936e9439SDimitry Andric unique_lock(unique_lock&& __u) _NOEXCEPT 1647a984708SDavid Chisnall : __m_(__u.__m_), __owns_(__u.__owns_) 1657a984708SDavid Chisnall {__u.__m_ = nullptr; __u.__owns_ = false;} 1667a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 167936e9439SDimitry Andric unique_lock& operator=(unique_lock&& __u) _NOEXCEPT 1687a984708SDavid Chisnall { 1697a984708SDavid Chisnall if (__owns_) 1707a984708SDavid Chisnall __m_->unlock(); 1717a984708SDavid Chisnall __m_ = __u.__m_; 1727a984708SDavid Chisnall __owns_ = __u.__owns_; 1737a984708SDavid Chisnall __u.__m_ = nullptr; 1747a984708SDavid Chisnall __u.__owns_ = false; 1757a984708SDavid Chisnall return *this; 1767a984708SDavid Chisnall } 1777a984708SDavid Chisnall 178540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 1797a984708SDavid Chisnall 1807a984708SDavid Chisnall void lock(); 1817a984708SDavid Chisnall bool try_lock(); 1827a984708SDavid Chisnall 1837a984708SDavid Chisnall template <class _Rep, class _Period> 1847a984708SDavid Chisnall bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); 1857a984708SDavid Chisnall template <class _Clock, class _Duration> 1867a984708SDavid Chisnall bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 1877a984708SDavid Chisnall 1887a984708SDavid Chisnall void unlock(); 1897a984708SDavid Chisnall 1907a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 191936e9439SDimitry Andric void swap(unique_lock& __u) _NOEXCEPT 1927a984708SDavid Chisnall { 1937a984708SDavid Chisnall _VSTD::swap(__m_, __u.__m_); 1947a984708SDavid Chisnall _VSTD::swap(__owns_, __u.__owns_); 1957a984708SDavid Chisnall } 1967a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 197936e9439SDimitry Andric mutex_type* release() _NOEXCEPT 1987a984708SDavid Chisnall { 1997a984708SDavid Chisnall mutex_type* __m = __m_; 2007a984708SDavid Chisnall __m_ = nullptr; 2017a984708SDavid Chisnall __owns_ = false; 2027a984708SDavid Chisnall return __m; 2037a984708SDavid Chisnall } 2047a984708SDavid Chisnall 2057a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 206936e9439SDimitry Andric bool owns_lock() const _NOEXCEPT {return __owns_;} 2077a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 20894e3ee44SDavid Chisnall _LIBCPP_EXPLICIT 209936e9439SDimitry Andric operator bool () const _NOEXCEPT {return __owns_;} 2107a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 211936e9439SDimitry Andric mutex_type* mutex() const _NOEXCEPT {return __m_;} 2127a984708SDavid Chisnall}; 2137a984708SDavid Chisnall 2147a984708SDavid Chisnalltemplate <class _Mutex> 2157a984708SDavid Chisnallvoid 2167a984708SDavid Chisnallunique_lock<_Mutex>::lock() 2177a984708SDavid Chisnall{ 2187a984708SDavid Chisnall if (__m_ == nullptr) 2197a984708SDavid Chisnall __throw_system_error(EPERM, "unique_lock::lock: references null mutex"); 2207a984708SDavid Chisnall if (__owns_) 2217a984708SDavid Chisnall __throw_system_error(EDEADLK, "unique_lock::lock: already locked"); 2227a984708SDavid Chisnall __m_->lock(); 2237a984708SDavid Chisnall __owns_ = true; 2247a984708SDavid Chisnall} 2257a984708SDavid Chisnall 2267a984708SDavid Chisnalltemplate <class _Mutex> 2277a984708SDavid Chisnallbool 2287a984708SDavid Chisnallunique_lock<_Mutex>::try_lock() 2297a984708SDavid Chisnall{ 2307a984708SDavid Chisnall if (__m_ == nullptr) 2317a984708SDavid Chisnall __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex"); 2327a984708SDavid Chisnall if (__owns_) 2337a984708SDavid Chisnall __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked"); 2347a984708SDavid Chisnall __owns_ = __m_->try_lock(); 2357a984708SDavid Chisnall return __owns_; 2367a984708SDavid Chisnall} 2377a984708SDavid Chisnall 2387a984708SDavid Chisnalltemplate <class _Mutex> 2397a984708SDavid Chisnalltemplate <class _Rep, class _Period> 2407a984708SDavid Chisnallbool 2417a984708SDavid Chisnallunique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) 2427a984708SDavid Chisnall{ 2437a984708SDavid Chisnall if (__m_ == nullptr) 2447a984708SDavid Chisnall __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex"); 2457a984708SDavid Chisnall if (__owns_) 2467a984708SDavid Chisnall __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked"); 2477a984708SDavid Chisnall __owns_ = __m_->try_lock_for(__d); 2487a984708SDavid Chisnall return __owns_; 2497a984708SDavid Chisnall} 2507a984708SDavid Chisnall 2517a984708SDavid Chisnalltemplate <class _Mutex> 2527a984708SDavid Chisnalltemplate <class _Clock, class _Duration> 2537a984708SDavid Chisnallbool 2547a984708SDavid Chisnallunique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 2557a984708SDavid Chisnall{ 2567a984708SDavid Chisnall if (__m_ == nullptr) 2577a984708SDavid Chisnall __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex"); 2587a984708SDavid Chisnall if (__owns_) 2597a984708SDavid Chisnall __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked"); 2607a984708SDavid Chisnall __owns_ = __m_->try_lock_until(__t); 2617a984708SDavid Chisnall return __owns_; 2627a984708SDavid Chisnall} 2637a984708SDavid Chisnall 2647a984708SDavid Chisnalltemplate <class _Mutex> 2657a984708SDavid Chisnallvoid 2667a984708SDavid Chisnallunique_lock<_Mutex>::unlock() 2677a984708SDavid Chisnall{ 2687a984708SDavid Chisnall if (!__owns_) 2697a984708SDavid Chisnall __throw_system_error(EPERM, "unique_lock::unlock: not locked"); 2707a984708SDavid Chisnall __m_->unlock(); 2717a984708SDavid Chisnall __owns_ = false; 2727a984708SDavid Chisnall} 2737a984708SDavid Chisnall 2747a984708SDavid Chisnalltemplate <class _Mutex> 2757a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 2767a984708SDavid Chisnallvoid 277936e9439SDimitry Andricswap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT 278936e9439SDimitry Andric {__x.swap(__y);} 2797a984708SDavid Chisnall 280d72607e9SDimitry Andric//enum class cv_status 281d72607e9SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM(cv_status) 2827a984708SDavid Chisnall{ 2837a984708SDavid Chisnall no_timeout, 2847a984708SDavid Chisnall timeout 2857a984708SDavid Chisnall}; 286d72607e9SDimitry Andric_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) 2877a984708SDavid Chisnall 2881bf9f7c1SDimitry Andricclass _LIBCPP_TYPE_VIS condition_variable 2897a984708SDavid Chisnall{ 290540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2917c82a1ecSDimitry Andric __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; 2927c82a1ecSDimitry Andric#else 2937c82a1ecSDimitry Andric __libcpp_condvar_t __cv_; 2947c82a1ecSDimitry Andric#endif 2957c82a1ecSDimitry Andric 2967a984708SDavid Chisnallpublic: 2977a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 298540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 299aed8d94eSDimitry Andric constexpr condition_variable() _NOEXCEPT = default; 300936e9439SDimitry Andric#else 3017c82a1ecSDimitry Andric condition_variable() _NOEXCEPT {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;} 302936e9439SDimitry Andric#endif 3037a984708SDavid Chisnall ~condition_variable(); 3047a984708SDavid Chisnall 3057a984708SDavid Chisnallprivate: 3067a984708SDavid Chisnall condition_variable(const condition_variable&); // = delete; 3077a984708SDavid Chisnall condition_variable& operator=(const condition_variable&); // = delete; 3087a984708SDavid Chisnall 3097a984708SDavid Chisnallpublic: 310936e9439SDimitry Andric void notify_one() _NOEXCEPT; 311936e9439SDimitry Andric void notify_all() _NOEXCEPT; 3127a984708SDavid Chisnall 313d72607e9SDimitry Andric void wait(unique_lock<mutex>& __lk) _NOEXCEPT; 3147a984708SDavid Chisnall template <class _Predicate> 315540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 3167a984708SDavid Chisnall void wait(unique_lock<mutex>& __lk, _Predicate __pred); 3177a984708SDavid Chisnall 3187a984708SDavid Chisnall template <class _Clock, class _Duration> 319540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 3207a984708SDavid Chisnall cv_status 3217a984708SDavid Chisnall wait_until(unique_lock<mutex>& __lk, 3227a984708SDavid Chisnall const chrono::time_point<_Clock, _Duration>& __t); 3237a984708SDavid Chisnall 3247a984708SDavid Chisnall template <class _Clock, class _Duration, class _Predicate> 325540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 3267a984708SDavid Chisnall bool 3277a984708SDavid Chisnall wait_until(unique_lock<mutex>& __lk, 3287a984708SDavid Chisnall const chrono::time_point<_Clock, _Duration>& __t, 3297a984708SDavid Chisnall _Predicate __pred); 3307a984708SDavid Chisnall 3317a984708SDavid Chisnall template <class _Rep, class _Period> 332540d2a8bSDimitry Andric _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 3337a984708SDavid Chisnall cv_status 3347a984708SDavid Chisnall wait_for(unique_lock<mutex>& __lk, 3357a984708SDavid Chisnall const chrono::duration<_Rep, _Period>& __d); 3367a984708SDavid Chisnall 3377a984708SDavid Chisnall template <class _Rep, class _Period, class _Predicate> 3387a984708SDavid Chisnall bool 3399729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3407a984708SDavid Chisnall wait_for(unique_lock<mutex>& __lk, 3417a984708SDavid Chisnall const chrono::duration<_Rep, _Period>& __d, 3427a984708SDavid Chisnall _Predicate __pred); 3437a984708SDavid Chisnall 3447c82a1ecSDimitry Andric typedef __libcpp_condvar_t* native_handle_type; 3457a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} 3467a984708SDavid Chisnall 3477a984708SDavid Chisnallprivate: 3487a984708SDavid Chisnall void __do_timed_wait(unique_lock<mutex>& __lk, 349d72607e9SDimitry Andric chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT; 3507a984708SDavid Chisnall}; 351d72607e9SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS 3527a984708SDavid Chisnall 3537a984708SDavid Chisnalltemplate <class _To, class _Rep, class _Period> 3547a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 3557a984708SDavid Chisnalltypename enable_if 3567a984708SDavid Chisnall< 3577a984708SDavid Chisnall chrono::__is_duration<_To>::value, 3587a984708SDavid Chisnall _To 3597a984708SDavid Chisnall>::type 3607a984708SDavid Chisnall__ceil(chrono::duration<_Rep, _Period> __d) 3617a984708SDavid Chisnall{ 3627a984708SDavid Chisnall using namespace chrono; 3637a984708SDavid Chisnall _To __r = duration_cast<_To>(__d); 3647a984708SDavid Chisnall if (__r < __d) 3657a984708SDavid Chisnall ++__r; 3667a984708SDavid Chisnall return __r; 3677a984708SDavid Chisnall} 3687a984708SDavid Chisnall 369d72607e9SDimitry Andric#ifndef _LIBCPP_HAS_NO_THREADS 3707a984708SDavid Chisnalltemplate <class _Predicate> 3717a984708SDavid Chisnallvoid 3727a984708SDavid Chisnallcondition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) 3737a984708SDavid Chisnall{ 3747a984708SDavid Chisnall while (!__pred()) 3757a984708SDavid Chisnall wait(__lk); 3767a984708SDavid Chisnall} 3777a984708SDavid Chisnall 3787a984708SDavid Chisnalltemplate <class _Clock, class _Duration> 3797a984708SDavid Chisnallcv_status 3807a984708SDavid Chisnallcondition_variable::wait_until(unique_lock<mutex>& __lk, 3817a984708SDavid Chisnall const chrono::time_point<_Clock, _Duration>& __t) 3827a984708SDavid Chisnall{ 3837a984708SDavid Chisnall using namespace chrono; 384936e9439SDimitry Andric wait_for(__lk, __t - _Clock::now()); 3857a984708SDavid Chisnall return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout; 3867a984708SDavid Chisnall} 3877a984708SDavid Chisnall 3887a984708SDavid Chisnalltemplate <class _Clock, class _Duration, class _Predicate> 3897a984708SDavid Chisnallbool 3907a984708SDavid Chisnallcondition_variable::wait_until(unique_lock<mutex>& __lk, 3917a984708SDavid Chisnall const chrono::time_point<_Clock, _Duration>& __t, 3927a984708SDavid Chisnall _Predicate __pred) 3937a984708SDavid Chisnall{ 3947a984708SDavid Chisnall while (!__pred()) 3957a984708SDavid Chisnall { 3967a984708SDavid Chisnall if (wait_until(__lk, __t) == cv_status::timeout) 3977a984708SDavid Chisnall return __pred(); 3987a984708SDavid Chisnall } 3997a984708SDavid Chisnall return true; 4007a984708SDavid Chisnall} 4017a984708SDavid Chisnall 4027a984708SDavid Chisnalltemplate <class _Rep, class _Period> 4037a984708SDavid Chisnallcv_status 4047a984708SDavid Chisnallcondition_variable::wait_for(unique_lock<mutex>& __lk, 4057a984708SDavid Chisnall const chrono::duration<_Rep, _Period>& __d) 4067a984708SDavid Chisnall{ 4077a984708SDavid Chisnall using namespace chrono; 408936e9439SDimitry Andric if (__d <= __d.zero()) 409936e9439SDimitry Andric return cv_status::timeout; 410936e9439SDimitry Andric typedef time_point<system_clock, duration<long double, nano> > __sys_tpf; 411936e9439SDimitry Andric typedef time_point<system_clock, nanoseconds> __sys_tpi; 412936e9439SDimitry Andric __sys_tpf _Max = __sys_tpi::max(); 4137a984708SDavid Chisnall steady_clock::time_point __c_now = steady_clock::now(); 4147a848d17SDimitry Andric system_clock::time_point __s_now = system_clock::now(); 415936e9439SDimitry Andric if (_Max - __d > __s_now) 4167a984708SDavid Chisnall __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d)); 417936e9439SDimitry Andric else 418936e9439SDimitry Andric __do_timed_wait(__lk, __sys_tpi::max()); 4197a984708SDavid Chisnall return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : 4207a984708SDavid Chisnall cv_status::timeout; 4217a984708SDavid Chisnall} 4227a984708SDavid Chisnall 4237a984708SDavid Chisnalltemplate <class _Rep, class _Period, class _Predicate> 4249729cf09SDimitry Andricinline 4257a984708SDavid Chisnallbool 4267a984708SDavid Chisnallcondition_variable::wait_for(unique_lock<mutex>& __lk, 4277a984708SDavid Chisnall const chrono::duration<_Rep, _Period>& __d, 4287a984708SDavid Chisnall _Predicate __pred) 4297a984708SDavid Chisnall{ 4307a984708SDavid Chisnall return wait_until(__lk, chrono::steady_clock::now() + __d, 4317a984708SDavid Chisnall _VSTD::move(__pred)); 4327a984708SDavid Chisnall} 4337a984708SDavid Chisnall 434d72607e9SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS 435d72607e9SDimitry Andric 4367a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 4377a984708SDavid Chisnall 438f9448bf3SDimitry Andric_LIBCPP_POP_MACROS 439f9448bf3SDimitry Andric 4407a984708SDavid Chisnall#endif // _LIBCPP___MUTEX_BASE 441