xref: /aosp_15_r20/external/libcxx/include/__mutex_base (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker// -*- C++ -*-
2*58b9f456SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3*58b9f456SAndroid Build Coastguard Worker//
4*58b9f456SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
5*58b9f456SAndroid Build Coastguard Worker//
6*58b9f456SAndroid Build Coastguard Worker// This file is dual licensed under the MIT and the University of Illinois Open
7*58b9f456SAndroid Build Coastguard Worker// Source Licenses. See LICENSE.TXT for details.
8*58b9f456SAndroid Build Coastguard Worker//
9*58b9f456SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
10*58b9f456SAndroid Build Coastguard Worker
11*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP___MUTEX_BASE
12*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP___MUTEX_BASE
13*58b9f456SAndroid Build Coastguard Worker
14*58b9f456SAndroid Build Coastguard Worker#include <__config>
15*58b9f456SAndroid Build Coastguard Worker#include <chrono>
16*58b9f456SAndroid Build Coastguard Worker#include <system_error>
17*58b9f456SAndroid Build Coastguard Worker#include <__threading_support>
18*58b9f456SAndroid Build Coastguard Worker
19*58b9f456SAndroid Build Coastguard Worker
20*58b9f456SAndroid Build Coastguard Worker#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21*58b9f456SAndroid Build Coastguard Worker#pragma GCC system_header
22*58b9f456SAndroid Build Coastguard Worker#endif
23*58b9f456SAndroid Build Coastguard Worker
24*58b9f456SAndroid Build Coastguard Worker_LIBCPP_PUSH_MACROS
25*58b9f456SAndroid Build Coastguard Worker#include <__undef_macros>
26*58b9f456SAndroid Build Coastguard Worker
27*58b9f456SAndroid Build Coastguard Worker
28*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_STD
29*58b9f456SAndroid Build Coastguard Worker
30*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_HAS_NO_THREADS
31*58b9f456SAndroid Build Coastguard Worker
32*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION
33*58b9f456SAndroid Build Coastguard Worker#  ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS
34*58b9f456SAndroid Build Coastguard Worker#    define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x))
35*58b9f456SAndroid Build Coastguard Worker#  else
36*58b9f456SAndroid Build Coastguard Worker#    define _LIBCPP_THREAD_SAFETY_ANNOTATION(x)
37*58b9f456SAndroid Build Coastguard Worker#  endif
38*58b9f456SAndroid Build Coastguard Worker#endif  // _LIBCPP_THREAD_SAFETY_ANNOTATION
39*58b9f456SAndroid Build Coastguard Worker
40*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex
41*58b9f456SAndroid Build Coastguard Worker{
42*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_CXX03_LANG
43*58b9f456SAndroid Build Coastguard Worker    __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER;
44*58b9f456SAndroid Build Coastguard Worker#else
45*58b9f456SAndroid Build Coastguard Worker    __libcpp_mutex_t __m_;
46*58b9f456SAndroid Build Coastguard Worker#endif
47*58b9f456SAndroid Build Coastguard Worker
48*58b9f456SAndroid Build Coastguard Workerpublic:
49*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
50*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_CXX03_LANG
51*58b9f456SAndroid Build Coastguard Worker    constexpr mutex() = default;
52*58b9f456SAndroid Build Coastguard Worker#else
53*58b9f456SAndroid Build Coastguard Worker    mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;}
54*58b9f456SAndroid Build Coastguard Worker#endif
55*58b9f456SAndroid Build Coastguard Worker    ~mutex();
56*58b9f456SAndroid Build Coastguard Worker
57*58b9f456SAndroid Build Coastguard Workerprivate:
58*58b9f456SAndroid Build Coastguard Worker    mutex(const mutex&);// = delete;
59*58b9f456SAndroid Build Coastguard Worker    mutex& operator=(const mutex&);// = delete;
60*58b9f456SAndroid Build Coastguard Worker
61*58b9f456SAndroid Build Coastguard Workerpublic:
62*58b9f456SAndroid Build Coastguard Worker    void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability());
63*58b9f456SAndroid Build Coastguard Worker    bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
64*58b9f456SAndroid Build Coastguard Worker    void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
65*58b9f456SAndroid Build Coastguard Worker
66*58b9f456SAndroid Build Coastguard Worker    typedef __libcpp_mutex_t* native_handle_type;
67*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
68*58b9f456SAndroid Build Coastguard Worker};
69*58b9f456SAndroid Build Coastguard Worker
70*58b9f456SAndroid Build Coastguard Workerstatic_assert(is_nothrow_default_constructible<mutex>::value,
71*58b9f456SAndroid Build Coastguard Worker              "the default constructor for std::mutex must be nothrow");
72*58b9f456SAndroid Build Coastguard Worker
73*58b9f456SAndroid Build Coastguard Workerstruct _LIBCPP_TYPE_VIS defer_lock_t {};
74*58b9f456SAndroid Build Coastguard Workerstruct _LIBCPP_TYPE_VIS try_to_lock_t {};
75*58b9f456SAndroid Build Coastguard Workerstruct _LIBCPP_TYPE_VIS adopt_lock_t {};
76*58b9f456SAndroid Build Coastguard Worker
77*58b9f456SAndroid Build Coastguard Worker#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
78*58b9f456SAndroid Build Coastguard Worker
79*58b9f456SAndroid Build Coastguard Workerextern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t  defer_lock;
80*58b9f456SAndroid Build Coastguard Workerextern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock;
81*58b9f456SAndroid Build Coastguard Workerextern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t  adopt_lock;
82*58b9f456SAndroid Build Coastguard Worker
83*58b9f456SAndroid Build Coastguard Worker#else
84*58b9f456SAndroid Build Coastguard Worker
85*58b9f456SAndroid Build Coastguard Worker/* _LIBCPP_INLINE_VAR */ constexpr defer_lock_t  defer_lock  = defer_lock_t();
86*58b9f456SAndroid Build Coastguard Worker/* _LIBCPP_INLINE_VAR */ constexpr try_to_lock_t try_to_lock = try_to_lock_t();
87*58b9f456SAndroid Build Coastguard Worker/* _LIBCPP_INLINE_VAR */ constexpr adopt_lock_t  adopt_lock  = adopt_lock_t();
88*58b9f456SAndroid Build Coastguard Worker
89*58b9f456SAndroid Build Coastguard Worker#endif
90*58b9f456SAndroid Build Coastguard Worker
91*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
92*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable)
93*58b9f456SAndroid Build Coastguard Workerlock_guard
94*58b9f456SAndroid Build Coastguard Worker{
95*58b9f456SAndroid Build Coastguard Workerpublic:
96*58b9f456SAndroid Build Coastguard Worker    typedef _Mutex mutex_type;
97*58b9f456SAndroid Build Coastguard Worker
98*58b9f456SAndroid Build Coastguard Workerprivate:
99*58b9f456SAndroid Build Coastguard Worker    mutex_type& __m_;
100*58b9f456SAndroid Build Coastguard Workerpublic:
101*58b9f456SAndroid Build Coastguard Worker
102*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
103*58b9f456SAndroid Build Coastguard Worker    explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m))
104*58b9f456SAndroid Build Coastguard Worker        : __m_(__m) {__m_.lock();}
105*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
106*58b9f456SAndroid Build Coastguard Worker    lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m))
107*58b9f456SAndroid Build Coastguard Worker        : __m_(__m) {}
108*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
109*58b9f456SAndroid Build Coastguard Worker    ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();}
110*58b9f456SAndroid Build Coastguard Worker
111*58b9f456SAndroid Build Coastguard Workerprivate:
112*58b9f456SAndroid Build Coastguard Worker    lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE;
113*58b9f456SAndroid Build Coastguard Worker    lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE;
114*58b9f456SAndroid Build Coastguard Worker};
115*58b9f456SAndroid Build Coastguard Worker
116*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
117*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TEMPLATE_VIS unique_lock
118*58b9f456SAndroid Build Coastguard Worker{
119*58b9f456SAndroid Build Coastguard Workerpublic:
120*58b9f456SAndroid Build Coastguard Worker    typedef _Mutex mutex_type;
121*58b9f456SAndroid Build Coastguard Worker
122*58b9f456SAndroid Build Coastguard Workerprivate:
123*58b9f456SAndroid Build Coastguard Worker    mutex_type* __m_;
124*58b9f456SAndroid Build Coastguard Worker    bool __owns_;
125*58b9f456SAndroid Build Coastguard Worker
126*58b9f456SAndroid Build Coastguard Workerpublic:
127*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
128*58b9f456SAndroid Build Coastguard Worker    unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
129*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
130*58b9f456SAndroid Build Coastguard Worker    explicit unique_lock(mutex_type& __m)
131*58b9f456SAndroid Build Coastguard Worker        : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();}
132*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
133*58b9f456SAndroid Build Coastguard Worker    unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
134*58b9f456SAndroid Build Coastguard Worker        : __m_(_VSTD::addressof(__m)), __owns_(false) {}
135*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
136*58b9f456SAndroid Build Coastguard Worker    unique_lock(mutex_type& __m, try_to_lock_t)
137*58b9f456SAndroid Build Coastguard Worker        : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {}
138*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
139*58b9f456SAndroid Build Coastguard Worker    unique_lock(mutex_type& __m, adopt_lock_t)
140*58b9f456SAndroid Build Coastguard Worker        : __m_(_VSTD::addressof(__m)), __owns_(true) {}
141*58b9f456SAndroid Build Coastguard Worker    template <class _Clock, class _Duration>
142*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
143*58b9f456SAndroid Build Coastguard Worker        unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
144*58b9f456SAndroid Build Coastguard Worker            : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {}
145*58b9f456SAndroid Build Coastguard Worker    template <class _Rep, class _Period>
146*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
147*58b9f456SAndroid Build Coastguard Worker        unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
148*58b9f456SAndroid Build Coastguard Worker            : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {}
149*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
150*58b9f456SAndroid Build Coastguard Worker    ~unique_lock()
151*58b9f456SAndroid Build Coastguard Worker    {
152*58b9f456SAndroid Build Coastguard Worker        if (__owns_)
153*58b9f456SAndroid Build Coastguard Worker            __m_->unlock();
154*58b9f456SAndroid Build Coastguard Worker    }
155*58b9f456SAndroid Build Coastguard Worker
156*58b9f456SAndroid Build Coastguard Workerprivate:
157*58b9f456SAndroid Build Coastguard Worker    unique_lock(unique_lock const&); // = delete;
158*58b9f456SAndroid Build Coastguard Worker    unique_lock& operator=(unique_lock const&); // = delete;
159*58b9f456SAndroid Build Coastguard Worker
160*58b9f456SAndroid Build Coastguard Workerpublic:
161*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_CXX03_LANG
162*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
163*58b9f456SAndroid Build Coastguard Worker    unique_lock(unique_lock&& __u) _NOEXCEPT
164*58b9f456SAndroid Build Coastguard Worker        : __m_(__u.__m_), __owns_(__u.__owns_)
165*58b9f456SAndroid Build Coastguard Worker        {__u.__m_ = nullptr; __u.__owns_ = false;}
166*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
167*58b9f456SAndroid Build Coastguard Worker    unique_lock& operator=(unique_lock&& __u) _NOEXCEPT
168*58b9f456SAndroid Build Coastguard Worker        {
169*58b9f456SAndroid Build Coastguard Worker            if (__owns_)
170*58b9f456SAndroid Build Coastguard Worker                __m_->unlock();
171*58b9f456SAndroid Build Coastguard Worker            __m_ = __u.__m_;
172*58b9f456SAndroid Build Coastguard Worker            __owns_ = __u.__owns_;
173*58b9f456SAndroid Build Coastguard Worker            __u.__m_ = nullptr;
174*58b9f456SAndroid Build Coastguard Worker            __u.__owns_ = false;
175*58b9f456SAndroid Build Coastguard Worker            return *this;
176*58b9f456SAndroid Build Coastguard Worker        }
177*58b9f456SAndroid Build Coastguard Worker
178*58b9f456SAndroid Build Coastguard Worker#endif  // _LIBCPP_CXX03_LANG
179*58b9f456SAndroid Build Coastguard Worker
180*58b9f456SAndroid Build Coastguard Worker    void lock();
181*58b9f456SAndroid Build Coastguard Worker    bool try_lock();
182*58b9f456SAndroid Build Coastguard Worker
183*58b9f456SAndroid Build Coastguard Worker    template <class _Rep, class _Period>
184*58b9f456SAndroid Build Coastguard Worker        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
185*58b9f456SAndroid Build Coastguard Worker    template <class _Clock, class _Duration>
186*58b9f456SAndroid Build Coastguard Worker        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
187*58b9f456SAndroid Build Coastguard Worker
188*58b9f456SAndroid Build Coastguard Worker    void unlock();
189*58b9f456SAndroid Build Coastguard Worker
190*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
191*58b9f456SAndroid Build Coastguard Worker    void swap(unique_lock& __u) _NOEXCEPT
192*58b9f456SAndroid Build Coastguard Worker    {
193*58b9f456SAndroid Build Coastguard Worker        _VSTD::swap(__m_, __u.__m_);
194*58b9f456SAndroid Build Coastguard Worker        _VSTD::swap(__owns_, __u.__owns_);
195*58b9f456SAndroid Build Coastguard Worker    }
196*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
197*58b9f456SAndroid Build Coastguard Worker    mutex_type* release() _NOEXCEPT
198*58b9f456SAndroid Build Coastguard Worker    {
199*58b9f456SAndroid Build Coastguard Worker        mutex_type* __m = __m_;
200*58b9f456SAndroid Build Coastguard Worker        __m_ = nullptr;
201*58b9f456SAndroid Build Coastguard Worker        __owns_ = false;
202*58b9f456SAndroid Build Coastguard Worker        return __m;
203*58b9f456SAndroid Build Coastguard Worker    }
204*58b9f456SAndroid Build Coastguard Worker
205*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
206*58b9f456SAndroid Build Coastguard Worker    bool owns_lock() const _NOEXCEPT {return __owns_;}
207*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
208*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_EXPLICIT
209*58b9f456SAndroid Build Coastguard Worker        operator bool () const _NOEXCEPT {return __owns_;}
210*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
211*58b9f456SAndroid Build Coastguard Worker    mutex_type* mutex() const _NOEXCEPT {return __m_;}
212*58b9f456SAndroid Build Coastguard Worker};
213*58b9f456SAndroid Build Coastguard Worker
214*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
215*58b9f456SAndroid Build Coastguard Workervoid
216*58b9f456SAndroid Build Coastguard Workerunique_lock<_Mutex>::lock()
217*58b9f456SAndroid Build Coastguard Worker{
218*58b9f456SAndroid Build Coastguard Worker    if (__m_ == nullptr)
219*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
220*58b9f456SAndroid Build Coastguard Worker    if (__owns_)
221*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
222*58b9f456SAndroid Build Coastguard Worker    __m_->lock();
223*58b9f456SAndroid Build Coastguard Worker    __owns_ = true;
224*58b9f456SAndroid Build Coastguard Worker}
225*58b9f456SAndroid Build Coastguard Worker
226*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
227*58b9f456SAndroid Build Coastguard Workerbool
228*58b9f456SAndroid Build Coastguard Workerunique_lock<_Mutex>::try_lock()
229*58b9f456SAndroid Build Coastguard Worker{
230*58b9f456SAndroid Build Coastguard Worker    if (__m_ == nullptr)
231*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
232*58b9f456SAndroid Build Coastguard Worker    if (__owns_)
233*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
234*58b9f456SAndroid Build Coastguard Worker    __owns_ = __m_->try_lock();
235*58b9f456SAndroid Build Coastguard Worker    return __owns_;
236*58b9f456SAndroid Build Coastguard Worker}
237*58b9f456SAndroid Build Coastguard Worker
238*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
239*58b9f456SAndroid Build Coastguard Workertemplate <class _Rep, class _Period>
240*58b9f456SAndroid Build Coastguard Workerbool
241*58b9f456SAndroid Build Coastguard Workerunique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
242*58b9f456SAndroid Build Coastguard Worker{
243*58b9f456SAndroid Build Coastguard Worker    if (__m_ == nullptr)
244*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
245*58b9f456SAndroid Build Coastguard Worker    if (__owns_)
246*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
247*58b9f456SAndroid Build Coastguard Worker    __owns_ = __m_->try_lock_for(__d);
248*58b9f456SAndroid Build Coastguard Worker    return __owns_;
249*58b9f456SAndroid Build Coastguard Worker}
250*58b9f456SAndroid Build Coastguard Worker
251*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
252*58b9f456SAndroid Build Coastguard Workertemplate <class _Clock, class _Duration>
253*58b9f456SAndroid Build Coastguard Workerbool
254*58b9f456SAndroid Build Coastguard Workerunique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
255*58b9f456SAndroid Build Coastguard Worker{
256*58b9f456SAndroid Build Coastguard Worker    if (__m_ == nullptr)
257*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
258*58b9f456SAndroid Build Coastguard Worker    if (__owns_)
259*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
260*58b9f456SAndroid Build Coastguard Worker    __owns_ = __m_->try_lock_until(__t);
261*58b9f456SAndroid Build Coastguard Worker    return __owns_;
262*58b9f456SAndroid Build Coastguard Worker}
263*58b9f456SAndroid Build Coastguard Worker
264*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
265*58b9f456SAndroid Build Coastguard Workervoid
266*58b9f456SAndroid Build Coastguard Workerunique_lock<_Mutex>::unlock()
267*58b9f456SAndroid Build Coastguard Worker{
268*58b9f456SAndroid Build Coastguard Worker    if (!__owns_)
269*58b9f456SAndroid Build Coastguard Worker        __throw_system_error(EPERM, "unique_lock::unlock: not locked");
270*58b9f456SAndroid Build Coastguard Worker    __m_->unlock();
271*58b9f456SAndroid Build Coastguard Worker    __owns_ = false;
272*58b9f456SAndroid Build Coastguard Worker}
273*58b9f456SAndroid Build Coastguard Worker
274*58b9f456SAndroid Build Coastguard Workertemplate <class _Mutex>
275*58b9f456SAndroid Build Coastguard Workerinline _LIBCPP_INLINE_VISIBILITY
276*58b9f456SAndroid Build Coastguard Workervoid
277*58b9f456SAndroid Build Coastguard Workerswap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT
278*58b9f456SAndroid Build Coastguard Worker    {__x.swap(__y);}
279*58b9f456SAndroid Build Coastguard Worker
280*58b9f456SAndroid Build Coastguard Worker//enum class cv_status
281*58b9f456SAndroid Build Coastguard Worker_LIBCPP_DECLARE_STRONG_ENUM(cv_status)
282*58b9f456SAndroid Build Coastguard Worker{
283*58b9f456SAndroid Build Coastguard Worker    no_timeout,
284*58b9f456SAndroid Build Coastguard Worker    timeout
285*58b9f456SAndroid Build Coastguard Worker};
286*58b9f456SAndroid Build Coastguard Worker_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
287*58b9f456SAndroid Build Coastguard Worker
288*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TYPE_VIS condition_variable
289*58b9f456SAndroid Build Coastguard Worker{
290*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_CXX03_LANG
291*58b9f456SAndroid Build Coastguard Worker    __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
292*58b9f456SAndroid Build Coastguard Worker#else
293*58b9f456SAndroid Build Coastguard Worker    __libcpp_condvar_t __cv_;
294*58b9f456SAndroid Build Coastguard Worker#endif
295*58b9f456SAndroid Build Coastguard Worker
296*58b9f456SAndroid Build Coastguard Workerpublic:
297*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
298*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_CXX03_LANG
299*58b9f456SAndroid Build Coastguard Worker    constexpr condition_variable() _NOEXCEPT = default;
300*58b9f456SAndroid Build Coastguard Worker#else
301*58b9f456SAndroid Build Coastguard Worker    condition_variable() _NOEXCEPT {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;}
302*58b9f456SAndroid Build Coastguard Worker#endif
303*58b9f456SAndroid Build Coastguard Worker    ~condition_variable();
304*58b9f456SAndroid Build Coastguard Worker
305*58b9f456SAndroid Build Coastguard Workerprivate:
306*58b9f456SAndroid Build Coastguard Worker    condition_variable(const condition_variable&); // = delete;
307*58b9f456SAndroid Build Coastguard Worker    condition_variable& operator=(const condition_variable&); // = delete;
308*58b9f456SAndroid Build Coastguard Worker
309*58b9f456SAndroid Build Coastguard Workerpublic:
310*58b9f456SAndroid Build Coastguard Worker    void notify_one() _NOEXCEPT;
311*58b9f456SAndroid Build Coastguard Worker    void notify_all() _NOEXCEPT;
312*58b9f456SAndroid Build Coastguard Worker
313*58b9f456SAndroid Build Coastguard Worker    void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
314*58b9f456SAndroid Build Coastguard Worker    template <class _Predicate>
315*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
316*58b9f456SAndroid Build Coastguard Worker        void wait(unique_lock<mutex>& __lk, _Predicate __pred);
317*58b9f456SAndroid Build Coastguard Worker
318*58b9f456SAndroid Build Coastguard Worker    template <class _Clock, class _Duration>
319*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
320*58b9f456SAndroid Build Coastguard Worker        cv_status
321*58b9f456SAndroid Build Coastguard Worker        wait_until(unique_lock<mutex>& __lk,
322*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<_Clock, _Duration>& __t);
323*58b9f456SAndroid Build Coastguard Worker
324*58b9f456SAndroid Build Coastguard Worker    template <class _Clock, class _Duration, class _Predicate>
325*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
326*58b9f456SAndroid Build Coastguard Worker        bool
327*58b9f456SAndroid Build Coastguard Worker        wait_until(unique_lock<mutex>& __lk,
328*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<_Clock, _Duration>& __t,
329*58b9f456SAndroid Build Coastguard Worker                   _Predicate __pred);
330*58b9f456SAndroid Build Coastguard Worker
331*58b9f456SAndroid Build Coastguard Worker    template <class _Rep, class _Period>
332*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
333*58b9f456SAndroid Build Coastguard Worker        cv_status
334*58b9f456SAndroid Build Coastguard Worker        wait_for(unique_lock<mutex>& __lk,
335*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<_Rep, _Period>& __d);
336*58b9f456SAndroid Build Coastguard Worker
337*58b9f456SAndroid Build Coastguard Worker    template <class _Rep, class _Period, class _Predicate>
338*58b9f456SAndroid Build Coastguard Worker        bool
339*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_INLINE_VISIBILITY
340*58b9f456SAndroid Build Coastguard Worker        wait_for(unique_lock<mutex>& __lk,
341*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<_Rep, _Period>& __d,
342*58b9f456SAndroid Build Coastguard Worker                 _Predicate __pred);
343*58b9f456SAndroid Build Coastguard Worker
344*58b9f456SAndroid Build Coastguard Worker    typedef __libcpp_condvar_t* native_handle_type;
345*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}
346*58b9f456SAndroid Build Coastguard Worker
347*58b9f456SAndroid Build Coastguard Workerprivate:
348*58b9f456SAndroid Build Coastguard Worker    void __do_timed_wait(unique_lock<mutex>& __lk,
349*58b9f456SAndroid Build Coastguard Worker       chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
350*58b9f456SAndroid Build Coastguard Worker};
351*58b9f456SAndroid Build Coastguard Worker#endif // !_LIBCPP_HAS_NO_THREADS
352*58b9f456SAndroid Build Coastguard Worker
353*58b9f456SAndroid Build Coastguard Workertemplate <class _To, class _Rep, class _Period>
354*58b9f456SAndroid Build Coastguard Workerinline _LIBCPP_INLINE_VISIBILITY
355*58b9f456SAndroid Build Coastguard Workertypename enable_if
356*58b9f456SAndroid Build Coastguard Worker<
357*58b9f456SAndroid Build Coastguard Worker    chrono::__is_duration<_To>::value,
358*58b9f456SAndroid Build Coastguard Worker    _To
359*58b9f456SAndroid Build Coastguard Worker>::type
360*58b9f456SAndroid Build Coastguard Worker__ceil(chrono::duration<_Rep, _Period> __d)
361*58b9f456SAndroid Build Coastguard Worker{
362*58b9f456SAndroid Build Coastguard Worker    using namespace chrono;
363*58b9f456SAndroid Build Coastguard Worker    _To __r = duration_cast<_To>(__d);
364*58b9f456SAndroid Build Coastguard Worker    if (__r < __d)
365*58b9f456SAndroid Build Coastguard Worker        ++__r;
366*58b9f456SAndroid Build Coastguard Worker    return __r;
367*58b9f456SAndroid Build Coastguard Worker}
368*58b9f456SAndroid Build Coastguard Worker
369*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_HAS_NO_THREADS
370*58b9f456SAndroid Build Coastguard Workertemplate <class _Predicate>
371*58b9f456SAndroid Build Coastguard Workervoid
372*58b9f456SAndroid Build Coastguard Workercondition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
373*58b9f456SAndroid Build Coastguard Worker{
374*58b9f456SAndroid Build Coastguard Worker    while (!__pred())
375*58b9f456SAndroid Build Coastguard Worker        wait(__lk);
376*58b9f456SAndroid Build Coastguard Worker}
377*58b9f456SAndroid Build Coastguard Worker
378*58b9f456SAndroid Build Coastguard Workertemplate <class _Clock, class _Duration>
379*58b9f456SAndroid Build Coastguard Workercv_status
380*58b9f456SAndroid Build Coastguard Workercondition_variable::wait_until(unique_lock<mutex>& __lk,
381*58b9f456SAndroid Build Coastguard Worker                               const chrono::time_point<_Clock, _Duration>& __t)
382*58b9f456SAndroid Build Coastguard Worker{
383*58b9f456SAndroid Build Coastguard Worker    using namespace chrono;
384*58b9f456SAndroid Build Coastguard Worker    wait_for(__lk, __t - _Clock::now());
385*58b9f456SAndroid Build Coastguard Worker    return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
386*58b9f456SAndroid Build Coastguard Worker}
387*58b9f456SAndroid Build Coastguard Worker
388*58b9f456SAndroid Build Coastguard Workertemplate <class _Clock, class _Duration, class _Predicate>
389*58b9f456SAndroid Build Coastguard Workerbool
390*58b9f456SAndroid Build Coastguard Workercondition_variable::wait_until(unique_lock<mutex>& __lk,
391*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<_Clock, _Duration>& __t,
392*58b9f456SAndroid Build Coastguard Worker                   _Predicate __pred)
393*58b9f456SAndroid Build Coastguard Worker{
394*58b9f456SAndroid Build Coastguard Worker    while (!__pred())
395*58b9f456SAndroid Build Coastguard Worker    {
396*58b9f456SAndroid Build Coastguard Worker        if (wait_until(__lk, __t) == cv_status::timeout)
397*58b9f456SAndroid Build Coastguard Worker            return __pred();
398*58b9f456SAndroid Build Coastguard Worker    }
399*58b9f456SAndroid Build Coastguard Worker    return true;
400*58b9f456SAndroid Build Coastguard Worker}
401*58b9f456SAndroid Build Coastguard Worker
402*58b9f456SAndroid Build Coastguard Workertemplate <class _Rep, class _Period>
403*58b9f456SAndroid Build Coastguard Workercv_status
404*58b9f456SAndroid Build Coastguard Workercondition_variable::wait_for(unique_lock<mutex>& __lk,
405*58b9f456SAndroid Build Coastguard Worker                             const chrono::duration<_Rep, _Period>& __d)
406*58b9f456SAndroid Build Coastguard Worker{
407*58b9f456SAndroid Build Coastguard Worker    using namespace chrono;
408*58b9f456SAndroid Build Coastguard Worker    if (__d <= __d.zero())
409*58b9f456SAndroid Build Coastguard Worker        return cv_status::timeout;
410*58b9f456SAndroid Build Coastguard Worker    typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;
411*58b9f456SAndroid Build Coastguard Worker    typedef time_point<system_clock, nanoseconds> __sys_tpi;
412*58b9f456SAndroid Build Coastguard Worker    __sys_tpf _Max = __sys_tpi::max();
413*58b9f456SAndroid Build Coastguard Worker    steady_clock::time_point __c_now = steady_clock::now();
414*58b9f456SAndroid Build Coastguard Worker    system_clock::time_point __s_now = system_clock::now();
415*58b9f456SAndroid Build Coastguard Worker    if (_Max - __d > __s_now)
416*58b9f456SAndroid Build Coastguard Worker        __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
417*58b9f456SAndroid Build Coastguard Worker    else
418*58b9f456SAndroid Build Coastguard Worker        __do_timed_wait(__lk, __sys_tpi::max());
419*58b9f456SAndroid Build Coastguard Worker    return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
420*58b9f456SAndroid Build Coastguard Worker                                                 cv_status::timeout;
421*58b9f456SAndroid Build Coastguard Worker}
422*58b9f456SAndroid Build Coastguard Worker
423*58b9f456SAndroid Build Coastguard Workertemplate <class _Rep, class _Period, class _Predicate>
424*58b9f456SAndroid Build Coastguard Workerinline
425*58b9f456SAndroid Build Coastguard Workerbool
426*58b9f456SAndroid Build Coastguard Workercondition_variable::wait_for(unique_lock<mutex>& __lk,
427*58b9f456SAndroid Build Coastguard Worker                             const chrono::duration<_Rep, _Period>& __d,
428*58b9f456SAndroid Build Coastguard Worker                             _Predicate __pred)
429*58b9f456SAndroid Build Coastguard Worker{
430*58b9f456SAndroid Build Coastguard Worker    return wait_until(__lk, chrono::steady_clock::now() + __d,
431*58b9f456SAndroid Build Coastguard Worker                      _VSTD::move(__pred));
432*58b9f456SAndroid Build Coastguard Worker}
433*58b9f456SAndroid Build Coastguard Worker
434*58b9f456SAndroid Build Coastguard Worker#endif // !_LIBCPP_HAS_NO_THREADS
435*58b9f456SAndroid Build Coastguard Worker
436*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_STD
437*58b9f456SAndroid Build Coastguard Worker
438*58b9f456SAndroid Build Coastguard Worker_LIBCPP_POP_MACROS
439*58b9f456SAndroid Build Coastguard Worker
440*58b9f456SAndroid Build Coastguard Worker#endif  // _LIBCPP___MUTEX_BASE
441