2
//===--------------------------- mutex ------------------------------------===//
4
// The LLVM Compiler Infrastructure
6
// This file is dual licensed under the MIT and the University of Illinois Open
7
// Source Licenses. See LICENSE.TXT for details.
9
//===----------------------------------------------------------------------===//
23
constexpr mutex() noexcept;
26
mutex(const mutex&) = delete;
27
mutex& operator=(const mutex&) = delete;
33
typedef pthread_mutex_t* native_handle_type;
34
native_handle_type native_handle();
43
recursive_mutex(const recursive_mutex&) = delete;
44
recursive_mutex& operator=(const recursive_mutex&) = delete;
47
bool try_lock() noexcept;
50
typedef pthread_mutex_t* native_handle_type;
51
native_handle_type native_handle();
60
timed_mutex(const timed_mutex&) = delete;
61
timed_mutex& operator=(const timed_mutex&) = delete;
65
template <class Rep, class Period>
66
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
67
template <class Clock, class Duration>
68
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
72
class recursive_timed_mutex
75
recursive_timed_mutex();
76
~recursive_timed_mutex();
78
recursive_timed_mutex(const recursive_timed_mutex&) = delete;
79
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
82
bool try_lock() noexcept;
83
template <class Rep, class Period>
84
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
85
template <class Clock, class Duration>
86
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
90
struct defer_lock_t {};
91
struct try_to_lock_t {};
92
struct adopt_lock_t {};
94
constexpr defer_lock_t defer_lock{};
95
constexpr try_to_lock_t try_to_lock{};
96
constexpr adopt_lock_t adopt_lock{};
98
template <class Mutex>
102
typedef Mutex mutex_type;
104
explicit lock_guard(mutex_type& m);
105
lock_guard(mutex_type& m, adopt_lock_t);
108
lock_guard(lock_guard const&) = delete;
109
lock_guard& operator=(lock_guard const&) = delete;
112
template <class Mutex>
116
typedef Mutex mutex_type;
117
unique_lock() noexcept;
118
explicit unique_lock(mutex_type& m);
119
unique_lock(mutex_type& m, defer_lock_t) noexcept;
120
unique_lock(mutex_type& m, try_to_lock_t);
121
unique_lock(mutex_type& m, adopt_lock_t);
122
template <class Clock, class Duration>
123
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
124
template <class Rep, class Period>
125
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
128
unique_lock(unique_lock const&) = delete;
129
unique_lock& operator=(unique_lock const&) = delete;
131
unique_lock(unique_lock&& u) noexcept;
132
unique_lock& operator=(unique_lock&& u) noexcept;
137
template <class Rep, class Period>
138
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
139
template <class Clock, class Duration>
140
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
144
void swap(unique_lock& u) noexcept;
145
mutex_type* release() noexcept;
147
bool owns_lock() const noexcept;
148
explicit operator bool () const noexcept;
149
mutex_type* mutex() const noexcept;
152
template <class Mutex>
153
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
155
template <class L1, class L2, class... L3>
156
int try_lock(L1&, L2&, L3&...);
157
template <class L1, class L2, class... L3>
158
void lock(L1&, L2&, L3&...);
162
constexpr once_flag() noexcept;
164
once_flag(const once_flag&) = delete;
165
once_flag& operator=(const once_flag&) = delete;
168
template<class Callable, class ...Args>
169
void call_once(once_flag& flag, Callable&& func, Args&&... args);
176
#include <__mutex_base>
177
#include <functional>
178
#ifndef _LIBCPP_HAS_NO_VARIADICS
182
#include <__undef_min_max>
184
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
185
#pragma GCC system_header
188
_LIBCPP_BEGIN_NAMESPACE_STD
190
class _LIBCPP_TYPE_VIS recursive_mutex
192
pthread_mutex_t __m_;
199
recursive_mutex(const recursive_mutex&); // = delete;
200
recursive_mutex& operator=(const recursive_mutex&); // = delete;
204
bool try_lock() _NOEXCEPT;
205
void unlock() _NOEXCEPT;
207
typedef pthread_mutex_t* native_handle_type;
208
_LIBCPP_INLINE_VISIBILITY
209
native_handle_type native_handle() {return &__m_;}
212
class _LIBCPP_TYPE_VIS timed_mutex
215
condition_variable __cv_;
222
timed_mutex(const timed_mutex&); // = delete;
223
timed_mutex& operator=(const timed_mutex&); // = delete;
227
bool try_lock() _NOEXCEPT;
228
template <class _Rep, class _Period>
229
_LIBCPP_INLINE_VISIBILITY
230
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
231
{return try_lock_until(chrono::steady_clock::now() + __d);}
232
template <class _Clock, class _Duration>
233
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
234
void unlock() _NOEXCEPT;
237
template <class _Clock, class _Duration>
239
timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
241
using namespace chrono;
242
unique_lock<mutex> __lk(__m_);
243
bool no_timeout = _Clock::now() < __t;
244
while (no_timeout && __locked_)
245
no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
254
class _LIBCPP_TYPE_VIS recursive_timed_mutex
257
condition_variable __cv_;
261
recursive_timed_mutex();
262
~recursive_timed_mutex();
265
recursive_timed_mutex(const recursive_timed_mutex&); // = delete;
266
recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete;
270
bool try_lock() _NOEXCEPT;
271
template <class _Rep, class _Period>
272
_LIBCPP_INLINE_VISIBILITY
273
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
274
{return try_lock_until(chrono::steady_clock::now() + __d);}
275
template <class _Clock, class _Duration>
276
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
277
void unlock() _NOEXCEPT;
280
template <class _Clock, class _Duration>
282
recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
284
using namespace chrono;
285
pthread_t __id = pthread_self();
286
unique_lock<mutex> lk(__m_);
287
if (pthread_equal(__id, __id_))
289
if (__count_ == numeric_limits<size_t>::max())
294
bool no_timeout = _Clock::now() < __t;
295
while (no_timeout && __count_ != 0)
296
no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout;
306
template <class _L0, class _L1>
308
try_lock(_L0& __l0, _L1& __l1)
310
unique_lock<_L0> __u0(__l0, try_to_lock);
311
if (__u0.owns_lock())
324
#ifndef _LIBCPP_HAS_NO_VARIADICS
326
template <class _L0, class _L1, class _L2, class... _L3>
328
try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3)
331
unique_lock<_L0> __u0(__l0, try_to_lock);
332
if (__u0.owns_lock())
334
__r = try_lock(__l1, __l2, __l3...);
343
#endif // _LIBCPP_HAS_NO_VARIADICS
345
template <class _L0, class _L1>
347
lock(_L0& __l0, _L1& __l1)
352
unique_lock<_L0> __u0(__l0);
361
unique_lock<_L1> __u1(__l1);
372
#ifndef _LIBCPP_HAS_NO_VARIADICS
374
template <class _L0, class _L1, class _L2, class ..._L3>
376
__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
384
unique_lock<_L0> __u0(__l0);
385
__i = try_lock(__l1, __l2, __l3...);
397
unique_lock<_L1> __u1(__l1);
398
__i = try_lock(__l2, __l3..., __l0);
405
if (__i == sizeof...(_L3) + 1)
412
__lock_first(__i - 2, __l2, __l3..., __l0, __l1);
418
template <class _L0, class _L1, class _L2, class ..._L3>
419
inline _LIBCPP_INLINE_VISIBILITY
421
lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
423
__lock_first(0, __l0, __l1, __l2, __l3...);
426
#endif // _LIBCPP_HAS_NO_VARIADICS
428
struct _LIBCPP_TYPE_VIS once_flag;
430
#ifndef _LIBCPP_HAS_NO_VARIADICS
432
template<class _Callable, class... _Args>
433
_LIBCPP_INLINE_VISIBILITY
434
void call_once(once_flag&, _Callable&&, _Args&&...);
436
#else // _LIBCPP_HAS_NO_VARIADICS
438
template<class _Callable>
439
_LIBCPP_INLINE_VISIBILITY
440
void call_once(once_flag&, _Callable);
442
#endif // _LIBCPP_HAS_NO_VARIADICS
444
struct _LIBCPP_TYPE_VIS once_flag
446
_LIBCPP_INLINE_VISIBILITY
448
once_flag() _NOEXCEPT : __state_(0) {}
451
once_flag(const once_flag&); // = delete;
452
once_flag& operator=(const once_flag&); // = delete;
454
unsigned long __state_;
456
#ifndef _LIBCPP_HAS_NO_VARIADICS
457
template<class _Callable, class... _Args>
459
void call_once(once_flag&, _Callable&&, _Args&&...);
460
#else // _LIBCPP_HAS_NO_VARIADICS
461
template<class _Callable>
463
void call_once(once_flag&, _Callable);
464
#endif // _LIBCPP_HAS_NO_VARIADICS
467
#ifndef _LIBCPP_HAS_NO_VARIADICS
470
class __call_once_param
474
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
475
_LIBCPP_INLINE_VISIBILITY
476
explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
478
_LIBCPP_INLINE_VISIBILITY
479
explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
482
_LIBCPP_INLINE_VISIBILITY
485
typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;
490
template <size_t ..._Indices>
491
_LIBCPP_INLINE_VISIBILITY
492
void __execute(__tuple_indices<_Indices...>)
494
__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
501
class __call_once_param
505
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
506
_LIBCPP_INLINE_VISIBILITY
507
explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
509
_LIBCPP_INLINE_VISIBILITY
510
explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
513
_LIBCPP_INLINE_VISIBILITY
524
__call_once_proxy(void* __vp)
526
__call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp);
530
void __call_once(volatile unsigned long&, void*, void(*)(void*));
532
#ifndef _LIBCPP_HAS_NO_VARIADICS
534
template<class _Callable, class... _Args>
535
inline _LIBCPP_INLINE_VISIBILITY
537
call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
539
if (__flag.__state_ != ~0ul)
541
typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp;
542
__call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)),
543
__decay_copy(_VSTD::forward<_Args>(__args))...));
544
__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
548
#else // _LIBCPP_HAS_NO_VARIADICS
550
template<class _Callable>
551
inline _LIBCPP_INLINE_VISIBILITY
553
call_once(once_flag& __flag, _Callable __func)
555
if (__flag.__state_ != ~0ul)
557
__call_once_param<_Callable> __p(__func);
558
__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
562
#endif // _LIBCPP_HAS_NO_VARIADICS
564
_LIBCPP_END_NAMESPACE_STD
566
#endif // _LIBCPP_MUTEX