blob: 3b2453f1ba1a8a6e389c51cfea48b7c663e450d7 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___MUTEX_BASE
12#define _LIBCPP___MUTEX_BASE
13
14#include <__config>
15#include <chrono>
16#include <system_error>
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000017#include <__threading_support>
Eric Fiselier018a3d52017-05-31 22:07:49 +000018
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000019
Howard Hinnant08e17472011-10-17 20:05:10 +000020#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000021#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000022#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000023
Eric Fiselier018a3d52017-05-31 22:07:49 +000024_LIBCPP_PUSH_MACROS
25#include <__undef_macros>
26
27
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000028_LIBCPP_BEGIN_NAMESPACE_STD
29
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +000030#ifndef _LIBCPP_HAS_NO_THREADS
31
Eric Fiseliera15e8c32016-03-16 02:30:06 +000032#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION
33# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
34# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
35# else
36# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
37# endif
38#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION
39
40class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000041{
Eric Fiselier690d9992017-04-18 23:05:08 +000042#ifndef _LIBCPP_CXX03_LANG
Marshall Clow65eb1e92016-07-18 17:23:06 +000043 __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
44#else
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000045 __libcpp_mutex_t __m_;
Marshall Clow65eb1e92016-07-18 17:23:06 +000046#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000047
48public:
Howard Hinnant333f50d2010-09-21 20:16:37 +000049 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier690d9992017-04-18 23:05:08 +000050#ifndef _LIBCPP_CXX03_LANG
Eric Fiselier276a69c2017-06-07 20:47:42 +000051 constexpr mutex() = default;
Howard Hinnant384608e2012-07-07 20:01:52 +000052#else
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000053 mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;}
Howard Hinnant384608e2012-07-07 20:01:52 +000054#endif
Marshall Clow65eb1e92016-07-18 17:23:06 +000055 ~mutex();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000056
57private:
58 mutex(const mutex&);// = delete;
59 mutex& operator=(const mutex&);// = delete;
60
61public:
Eric Fiseliera15e8c32016-03-16 02:30:06 +000062 void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
63 bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
64 void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000065
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000066 typedef __libcpp_mutex_t* native_handle_type;
Howard Hinnant333f50d2010-09-21 20:16:37 +000067 _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000068};
69
Eric Fiselier276a69c2017-06-07 20:47:42 +000070static_assert(is_nothrow_default_constructible<mutex>::value,
71 "the default constructor for std::mutex must be nothrow");
72
Howard Hinnant83eade62013-03-06 23:30:19 +000073struct _LIBCPP_TYPE_VIS defer_lock_t {};
74struct _LIBCPP_TYPE_VIS try_to_lock_t {};
75struct _LIBCPP_TYPE_VIS adopt_lock_t {};
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000076
Eric Fiselier690d9992017-04-18 23:05:08 +000077#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_MUTEX)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000078
Howard Hinnant499c61f2012-07-21 16:13:09 +000079extern const defer_lock_t defer_lock;
80extern const try_to_lock_t try_to_lock;
81extern const adopt_lock_t adopt_lock;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000082
Howard Hinnant499c61f2012-07-21 16:13:09 +000083#else
84
85constexpr defer_lock_t defer_lock = defer_lock_t();
86constexpr try_to_lock_t try_to_lock = try_to_lock_t();
87constexpr adopt_lock_t adopt_lock = adopt_lock_t();
88
89#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000090
91template <class _Mutex>
Eric Fiselierc3589a82017-01-04 23:56:00 +000092class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
Eric Fiselier10b52a02016-06-14 03:48:09 +000093lock_guard
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000094{
95public:
96 typedef _Mutex mutex_type;
97
98private:
99 mutex_type& __m_;
100public:
101
Howard Hinnant333f50d2010-09-21 20:16:37 +0000102 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera15e8c32016-03-16 02:30:06 +0000103 explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000104 : __m_(__m) {__m_.lock();}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000105 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera15e8c32016-03-16 02:30:06 +0000106 lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000107 : __m_(__m) {}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000108 _LIBCPP_INLINE_VISIBILITY
Eric Fiseliera15e8c32016-03-16 02:30:06 +0000109 ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000110
111private:
Eric Fiselier10b52a02016-06-14 03:48:09 +0000112 lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE;
113 lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000114};
115
116template <class _Mutex>
Eric Fiselierc3589a82017-01-04 23:56:00 +0000117class _LIBCPP_TEMPLATE_VIS unique_lock
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000118{
119public:
120 typedef _Mutex mutex_type;
121
122private:
123 mutex_type* __m_;
124 bool __owns_;
125
126public:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000127 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000128 unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000129 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000130 explicit unique_lock(mutex_type& __m)
Marshall Clow81652492016-04-13 17:02:23 +0000131 : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000132 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000133 unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
Marshall Clow81652492016-04-13 17:02:23 +0000134 : __m_(_VSTD::addressof(__m)), __owns_(false) {}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000135 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000136 unique_lock(mutex_type& __m, try_to_lock_t)
Marshall Clow81652492016-04-13 17:02:23 +0000137 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000138 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000139 unique_lock(mutex_type& __m, adopt_lock_t)
Marshall Clow81652492016-04-13 17:02:23 +0000140 : __m_(_VSTD::addressof(__m)), __owns_(true) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000141 template <class _Clock, class _Duration>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000142 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000143 unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
Marshall Clow81652492016-04-13 17:02:23 +0000144 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145 template <class _Rep, class _Period>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000146 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147 unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
Marshall Clow81652492016-04-13 17:02:23 +0000148 : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000149 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000150 ~unique_lock()
151 {
152 if (__owns_)
153 __m_->unlock();
154 }
155
156private:
157 unique_lock(unique_lock const&); // = delete;
158 unique_lock& operator=(unique_lock const&); // = delete;
159
160public:
Eric Fiselier690d9992017-04-18 23:05:08 +0000161#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant333f50d2010-09-21 20:16:37 +0000162 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000163 unique_lock(unique_lock&& __u) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000164 : __m_(__u.__m_), __owns_(__u.__owns_)
165 {__u.__m_ = nullptr; __u.__owns_ = false;}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000166 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000167 unique_lock& operator=(unique_lock&& __u) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000168 {
169 if (__owns_)
170 __m_->unlock();
171 __m_ = __u.__m_;
172 __owns_ = __u.__owns_;
173 __u.__m_ = nullptr;
174 __u.__owns_ = false;
175 return *this;
176 }
Howard Hinnantac417fa2010-11-28 19:41:07 +0000177
Eric Fiselier690d9992017-04-18 23:05:08 +0000178#endif // _LIBCPP_CXX03_LANG
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000179
180 void lock();
181 bool try_lock();
182
183 template <class _Rep, class _Period>
184 bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
185 template <class _Clock, class _Duration>
186 bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
187
188 void unlock();
189
Howard Hinnant333f50d2010-09-21 20:16:37 +0000190 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000191 void swap(unique_lock& __u) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000193 _VSTD::swap(__m_, __u.__m_);
194 _VSTD::swap(__owns_, __u.__owns_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000195 }
Howard Hinnant333f50d2010-09-21 20:16:37 +0000196 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000197 mutex_type* release() _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000198 {
199 mutex_type* __m = __m_;
200 __m_ = nullptr;
201 __owns_ = false;
202 return __m;
203 }
204
Howard Hinnant333f50d2010-09-21 20:16:37 +0000205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000206 bool owns_lock() const _NOEXCEPT {return __owns_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000207 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant77861882012-02-21 21:46:43 +0000208 _LIBCPP_EXPLICIT
Howard Hinnant499c61f2012-07-21 16:13:09 +0000209 operator bool () const _NOEXCEPT {return __owns_;}
Howard Hinnant333f50d2010-09-21 20:16:37 +0000210 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant499c61f2012-07-21 16:13:09 +0000211 mutex_type* mutex() const _NOEXCEPT {return __m_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000212};
213
214template <class _Mutex>
215void
216unique_lock<_Mutex>::lock()
217{
218 if (__m_ == nullptr)
219 __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
220 if (__owns_)
221 __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
222 __m_->lock();
223 __owns_ = true;
224}
225
226template <class _Mutex>
227bool
228unique_lock<_Mutex>::try_lock()
229{
230 if (__m_ == nullptr)
231 __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
232 if (__owns_)
233 __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
234 __owns_ = __m_->try_lock();
235 return __owns_;
236}
237
238template <class _Mutex>
239template <class _Rep, class _Period>
240bool
241unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
242{
243 if (__m_ == nullptr)
244 __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
245 if (__owns_)
246 __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
247 __owns_ = __m_->try_lock_for(__d);
248 return __owns_;
249}
250
251template <class _Mutex>
252template <class _Clock, class _Duration>
253bool
254unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
255{
256 if (__m_ == nullptr)
257 __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
258 if (__owns_)
259 __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
260 __owns_ = __m_->try_lock_until(__t);
261 return __owns_;
262}
263
264template <class _Mutex>
265void
266unique_lock<_Mutex>::unlock()
267{
268 if (!__owns_)
269 __throw_system_error(EPERM, "unique_lock::unlock: not locked");
270 __m_->unlock();
271 __owns_ = false;
272}
273
274template <class _Mutex>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000275inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000276void
Howard Hinnant499c61f2012-07-21 16:13:09 +0000277swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT
278 {__x.swap(__y);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000279
Marshall Clow239bc422013-12-23 22:14:27 +0000280//enum class cv_status
281_LIBCPP_DECLARE_STRONG_ENUM(cv_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000282{
Marshall Clow239bc422013-12-23 22:14:27 +0000283 no_timeout,
284 timeout
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000285};
Marshall Clow239bc422013-12-23 22:14:27 +0000286_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000287
Howard Hinnant83eade62013-03-06 23:30:19 +0000288class _LIBCPP_TYPE_VIS condition_variable
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000289{
Eric Fiselier690d9992017-04-18 23:05:08 +0000290#ifndef _LIBCPP_CXX03_LANG
Marshall Clow65eb1e92016-07-18 17:23:06 +0000291 __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
292#else
293 __libcpp_condvar_t __cv_;
294#endif
295
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000296public:
Howard Hinnant333f50d2010-09-21 20:16:37 +0000297 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier690d9992017-04-18 23:05:08 +0000298#ifndef _LIBCPP_CXX03_LANG
Eric Fiselier8c570322016-11-18 06:42:17 +0000299 constexpr condition_variable() _NOEXCEPT = default;
Howard Hinnant384608e2012-07-07 20:01:52 +0000300#else
Marshall Clow65eb1e92016-07-18 17:23:06 +0000301 condition_variable() _NOEXCEPT {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;}
Howard Hinnant384608e2012-07-07 20:01:52 +0000302#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000303 ~condition_variable();
304
305private:
306 condition_variable(const condition_variable&); // = delete;
307 condition_variable& operator=(const condition_variable&); // = delete;
308
309public:
Howard Hinnantc8f74132012-07-21 16:32:53 +0000310 void notify_one() _NOEXCEPT;
311 void notify_all() _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000312
Marshall Clowb0767852014-03-26 02:45:04 +0000313 void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000314 template <class _Predicate>
Shoaib Meenai6b734922017-03-02 03:22:18 +0000315 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000316 void wait(unique_lock<mutex>& __lk, _Predicate __pred);
317
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000318 template <class _Clock, class _Duration>
Shoaib Meenai6b734922017-03-02 03:22:18 +0000319 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000320 cv_status
321 wait_until(unique_lock<mutex>& __lk,
322 const chrono::time_point<_Clock, _Duration>& __t);
323
324 template <class _Clock, class _Duration, class _Predicate>
Shoaib Meenai6b734922017-03-02 03:22:18 +0000325 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000326 bool
327 wait_until(unique_lock<mutex>& __lk,
328 const chrono::time_point<_Clock, _Duration>& __t,
329 _Predicate __pred);
330
331 template <class _Rep, class _Period>
Shoaib Meenai6b734922017-03-02 03:22:18 +0000332 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000333 cv_status
334 wait_for(unique_lock<mutex>& __lk,
335 const chrono::duration<_Rep, _Period>& __d);
336
337 template <class _Rep, class _Period, class _Predicate>
338 bool
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000339 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000340 wait_for(unique_lock<mutex>& __lk,
341 const chrono::duration<_Rep, _Period>& __d,
342 _Predicate __pred);
343
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000344 typedef __libcpp_condvar_t* native_handle_type;
Howard Hinnant333f50d2010-09-21 20:16:37 +0000345 _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000346
347private:
348 void __do_timed_wait(unique_lock<mutex>& __lk,
Marshall Clowb0767852014-03-26 02:45:04 +0000349 chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000350};
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +0000351#endif // !_LIBCPP_HAS_NO_THREADS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000352
353template <class _To, class _Rep, class _Period>
Howard Hinnant333f50d2010-09-21 20:16:37 +0000354inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000355typename enable_if
356<
357 chrono::__is_duration<_To>::value,
358 _To
359>::type
360__ceil(chrono::duration<_Rep, _Period> __d)
361{
362 using namespace chrono;
363 _To __r = duration_cast<_To>(__d);
364 if (__r < __d)
365 ++__r;
366 return __r;
367}
368
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +0000369#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000370template <class _Predicate>
371void
372condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
373{
374 while (!__pred())
375 wait(__lk);
376}
377
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000378template <class _Clock, class _Duration>
379cv_status
380condition_variable::wait_until(unique_lock<mutex>& __lk,
381 const chrono::time_point<_Clock, _Duration>& __t)
382{
383 using namespace chrono;
Howard Hinnantcf115d22012-08-30 19:14:33 +0000384 wait_for(__lk, __t - _Clock::now());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000385 return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
386}
387
388template <class _Clock, class _Duration, class _Predicate>
389bool
390condition_variable::wait_until(unique_lock<mutex>& __lk,
391 const chrono::time_point<_Clock, _Duration>& __t,
392 _Predicate __pred)
393{
394 while (!__pred())
395 {
396 if (wait_until(__lk, __t) == cv_status::timeout)
397 return __pred();
398 }
399 return true;
400}
401
402template <class _Rep, class _Period>
403cv_status
404condition_variable::wait_for(unique_lock<mutex>& __lk,
405 const chrono::duration<_Rep, _Period>& __d)
406{
407 using namespace chrono;
Howard Hinnantcf115d22012-08-30 19:14:33 +0000408 if (__d <= __d.zero())
409 return cv_status::timeout;
410 typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;
411 typedef time_point<system_clock, nanoseconds> __sys_tpi;
412 __sys_tpf _Max = __sys_tpi::max();
Howard Hinnantf8f85212010-11-20 19:16:30 +0000413 steady_clock::time_point __c_now = steady_clock::now();
Marshall Clowf3e76772017-01-09 22:32:11 +0000414 system_clock::time_point __s_now = system_clock::now();
Howard Hinnantcf115d22012-08-30 19:14:33 +0000415 if (_Max - __d > __s_now)
416 __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
417 else
418 __do_timed_wait(__lk, __sys_tpi::max());
Howard Hinnantf8f85212010-11-20 19:16:30 +0000419 return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
420 cv_status::timeout;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000421}
422
423template <class _Rep, class _Period, class _Predicate>
Evgeniy Stepanova3b25f82015-11-07 01:22:13 +0000424inline
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000425bool
426condition_variable::wait_for(unique_lock<mutex>& __lk,
427 const chrono::duration<_Rep, _Period>& __d,
428 _Predicate __pred)
429{
Howard Hinnantf8f85212010-11-20 19:16:30 +0000430 return wait_until(__lk, chrono::steady_clock::now() + __d,
Howard Hinnant0949eed2011-06-30 21:18:19 +0000431 _VSTD::move(__pred));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432}
433
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +0000434#endif // !_LIBCPP_HAS_NO_THREADS
435
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000436_LIBCPP_END_NAMESPACE_STD
437
Eric Fiselier018a3d52017-05-31 22:07:49 +0000438_LIBCPP_POP_MACROS
439
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000440#endif // _LIBCPP___MUTEX_BASE