xref: /aosp_15_r20/external/libcxx/include/condition_variable (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker// -*- C++ -*-
2*58b9f456SAndroid Build Coastguard Worker//===---------------------- condition_variable ----------------------------===//
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_CONDITION_VARIABLE
12*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP_CONDITION_VARIABLE
13*58b9f456SAndroid Build Coastguard Worker
14*58b9f456SAndroid Build Coastguard Worker/*
15*58b9f456SAndroid Build Coastguard Worker    condition_variable synopsis
16*58b9f456SAndroid Build Coastguard Worker
17*58b9f456SAndroid Build Coastguard Workernamespace std
18*58b9f456SAndroid Build Coastguard Worker{
19*58b9f456SAndroid Build Coastguard Worker
20*58b9f456SAndroid Build Coastguard Workerenum class cv_status { no_timeout, timeout };
21*58b9f456SAndroid Build Coastguard Worker
22*58b9f456SAndroid Build Coastguard Workerclass condition_variable
23*58b9f456SAndroid Build Coastguard Worker{
24*58b9f456SAndroid Build Coastguard Workerpublic:
25*58b9f456SAndroid Build Coastguard Worker    condition_variable();
26*58b9f456SAndroid Build Coastguard Worker    ~condition_variable();
27*58b9f456SAndroid Build Coastguard Worker
28*58b9f456SAndroid Build Coastguard Worker    condition_variable(const condition_variable&) = delete;
29*58b9f456SAndroid Build Coastguard Worker    condition_variable& operator=(const condition_variable&) = delete;
30*58b9f456SAndroid Build Coastguard Worker
31*58b9f456SAndroid Build Coastguard Worker    void notify_one() noexcept;
32*58b9f456SAndroid Build Coastguard Worker    void notify_all() noexcept;
33*58b9f456SAndroid Build Coastguard Worker
34*58b9f456SAndroid Build Coastguard Worker    void wait(unique_lock<mutex>& lock);
35*58b9f456SAndroid Build Coastguard Worker    template <class Predicate>
36*58b9f456SAndroid Build Coastguard Worker        void wait(unique_lock<mutex>& lock, Predicate pred);
37*58b9f456SAndroid Build Coastguard Worker
38*58b9f456SAndroid Build Coastguard Worker    template <class Clock, class Duration>
39*58b9f456SAndroid Build Coastguard Worker        cv_status
40*58b9f456SAndroid Build Coastguard Worker        wait_until(unique_lock<mutex>& lock,
41*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<Clock, Duration>& abs_time);
42*58b9f456SAndroid Build Coastguard Worker
43*58b9f456SAndroid Build Coastguard Worker    template <class Clock, class Duration, class Predicate>
44*58b9f456SAndroid Build Coastguard Worker        bool
45*58b9f456SAndroid Build Coastguard Worker        wait_until(unique_lock<mutex>& lock,
46*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<Clock, Duration>& abs_time,
47*58b9f456SAndroid Build Coastguard Worker                   Predicate pred);
48*58b9f456SAndroid Build Coastguard Worker
49*58b9f456SAndroid Build Coastguard Worker    template <class Rep, class Period>
50*58b9f456SAndroid Build Coastguard Worker        cv_status
51*58b9f456SAndroid Build Coastguard Worker        wait_for(unique_lock<mutex>& lock,
52*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<Rep, Period>& rel_time);
53*58b9f456SAndroid Build Coastguard Worker
54*58b9f456SAndroid Build Coastguard Worker    template <class Rep, class Period, class Predicate>
55*58b9f456SAndroid Build Coastguard Worker        bool
56*58b9f456SAndroid Build Coastguard Worker        wait_for(unique_lock<mutex>& lock,
57*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<Rep, Period>& rel_time,
58*58b9f456SAndroid Build Coastguard Worker                 Predicate pred);
59*58b9f456SAndroid Build Coastguard Worker
60*58b9f456SAndroid Build Coastguard Worker    typedef pthread_cond_t* native_handle_type;
61*58b9f456SAndroid Build Coastguard Worker    native_handle_type native_handle();
62*58b9f456SAndroid Build Coastguard Worker};
63*58b9f456SAndroid Build Coastguard Worker
64*58b9f456SAndroid Build Coastguard Workervoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
65*58b9f456SAndroid Build Coastguard Worker
66*58b9f456SAndroid Build Coastguard Workerclass condition_variable_any
67*58b9f456SAndroid Build Coastguard Worker{
68*58b9f456SAndroid Build Coastguard Workerpublic:
69*58b9f456SAndroid Build Coastguard Worker    condition_variable_any();
70*58b9f456SAndroid Build Coastguard Worker    ~condition_variable_any();
71*58b9f456SAndroid Build Coastguard Worker
72*58b9f456SAndroid Build Coastguard Worker    condition_variable_any(const condition_variable_any&) = delete;
73*58b9f456SAndroid Build Coastguard Worker    condition_variable_any& operator=(const condition_variable_any&) = delete;
74*58b9f456SAndroid Build Coastguard Worker
75*58b9f456SAndroid Build Coastguard Worker    void notify_one() noexcept;
76*58b9f456SAndroid Build Coastguard Worker    void notify_all() noexcept;
77*58b9f456SAndroid Build Coastguard Worker
78*58b9f456SAndroid Build Coastguard Worker    template <class Lock>
79*58b9f456SAndroid Build Coastguard Worker        void wait(Lock& lock);
80*58b9f456SAndroid Build Coastguard Worker    template <class Lock, class Predicate>
81*58b9f456SAndroid Build Coastguard Worker        void wait(Lock& lock, Predicate pred);
82*58b9f456SAndroid Build Coastguard Worker
83*58b9f456SAndroid Build Coastguard Worker    template <class Lock, class Clock, class Duration>
84*58b9f456SAndroid Build Coastguard Worker        cv_status
85*58b9f456SAndroid Build Coastguard Worker        wait_until(Lock& lock,
86*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<Clock, Duration>& abs_time);
87*58b9f456SAndroid Build Coastguard Worker
88*58b9f456SAndroid Build Coastguard Worker    template <class Lock, class Clock, class Duration, class Predicate>
89*58b9f456SAndroid Build Coastguard Worker        bool
90*58b9f456SAndroid Build Coastguard Worker        wait_until(Lock& lock,
91*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<Clock, Duration>& abs_time,
92*58b9f456SAndroid Build Coastguard Worker                   Predicate pred);
93*58b9f456SAndroid Build Coastguard Worker
94*58b9f456SAndroid Build Coastguard Worker    template <class Lock, class Rep, class Period>
95*58b9f456SAndroid Build Coastguard Worker        cv_status
96*58b9f456SAndroid Build Coastguard Worker        wait_for(Lock& lock,
97*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<Rep, Period>& rel_time);
98*58b9f456SAndroid Build Coastguard Worker
99*58b9f456SAndroid Build Coastguard Worker    template <class Lock, class Rep, class Period, class Predicate>
100*58b9f456SAndroid Build Coastguard Worker        bool
101*58b9f456SAndroid Build Coastguard Worker        wait_for(Lock& lock,
102*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<Rep, Period>& rel_time,
103*58b9f456SAndroid Build Coastguard Worker                 Predicate pred);
104*58b9f456SAndroid Build Coastguard Worker};
105*58b9f456SAndroid Build Coastguard Worker
106*58b9f456SAndroid Build Coastguard Worker}  // std
107*58b9f456SAndroid Build Coastguard Worker
108*58b9f456SAndroid Build Coastguard Worker*/
109*58b9f456SAndroid Build Coastguard Worker
110*58b9f456SAndroid Build Coastguard Worker#include <__config>
111*58b9f456SAndroid Build Coastguard Worker#include <__mutex_base>
112*58b9f456SAndroid Build Coastguard Worker#include <memory>
113*58b9f456SAndroid Build Coastguard Worker
114*58b9f456SAndroid Build Coastguard Worker#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
115*58b9f456SAndroid Build Coastguard Worker#pragma GCC system_header
116*58b9f456SAndroid Build Coastguard Worker#endif
117*58b9f456SAndroid Build Coastguard Worker
118*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_HAS_NO_THREADS
119*58b9f456SAndroid Build Coastguard Worker
120*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_STD
121*58b9f456SAndroid Build Coastguard Worker
122*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TYPE_VIS condition_variable_any
123*58b9f456SAndroid Build Coastguard Worker{
124*58b9f456SAndroid Build Coastguard Worker    condition_variable __cv_;
125*58b9f456SAndroid Build Coastguard Worker    shared_ptr<mutex>  __mut_;
126*58b9f456SAndroid Build Coastguard Workerpublic:
127*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
128*58b9f456SAndroid Build Coastguard Worker    condition_variable_any();
129*58b9f456SAndroid Build Coastguard Worker
130*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
131*58b9f456SAndroid Build Coastguard Worker    void notify_one() _NOEXCEPT;
132*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
133*58b9f456SAndroid Build Coastguard Worker    void notify_all() _NOEXCEPT;
134*58b9f456SAndroid Build Coastguard Worker
135*58b9f456SAndroid Build Coastguard Worker    template <class _Lock>
136*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
137*58b9f456SAndroid Build Coastguard Worker        void wait(_Lock& __lock);
138*58b9f456SAndroid Build Coastguard Worker    template <class _Lock, class _Predicate>
139*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_INLINE_VISIBILITY
140*58b9f456SAndroid Build Coastguard Worker        void wait(_Lock& __lock, _Predicate __pred);
141*58b9f456SAndroid Build Coastguard Worker
142*58b9f456SAndroid Build Coastguard Worker    template <class _Lock, class _Clock, class _Duration>
143*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
144*58b9f456SAndroid Build Coastguard Worker        cv_status
145*58b9f456SAndroid Build Coastguard Worker        wait_until(_Lock& __lock,
146*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<_Clock, _Duration>& __t);
147*58b9f456SAndroid Build Coastguard Worker
148*58b9f456SAndroid Build Coastguard Worker    template <class _Lock, class _Clock, class _Duration, class _Predicate>
149*58b9f456SAndroid Build Coastguard Worker        bool
150*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_INLINE_VISIBILITY
151*58b9f456SAndroid Build Coastguard Worker        wait_until(_Lock& __lock,
152*58b9f456SAndroid Build Coastguard Worker                   const chrono::time_point<_Clock, _Duration>& __t,
153*58b9f456SAndroid Build Coastguard Worker                   _Predicate __pred);
154*58b9f456SAndroid Build Coastguard Worker
155*58b9f456SAndroid Build Coastguard Worker    template <class _Lock, class _Rep, class _Period>
156*58b9f456SAndroid Build Coastguard Worker        cv_status
157*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_INLINE_VISIBILITY
158*58b9f456SAndroid Build Coastguard Worker        wait_for(_Lock& __lock,
159*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<_Rep, _Period>& __d);
160*58b9f456SAndroid Build Coastguard Worker
161*58b9f456SAndroid Build Coastguard Worker    template <class _Lock, class _Rep, class _Period, class _Predicate>
162*58b9f456SAndroid Build Coastguard Worker        bool
163*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_INLINE_VISIBILITY
164*58b9f456SAndroid Build Coastguard Worker        wait_for(_Lock& __lock,
165*58b9f456SAndroid Build Coastguard Worker                 const chrono::duration<_Rep, _Period>& __d,
166*58b9f456SAndroid Build Coastguard Worker                 _Predicate __pred);
167*58b9f456SAndroid Build Coastguard Worker};
168*58b9f456SAndroid Build Coastguard Worker
169*58b9f456SAndroid Build Coastguard Workerinline
170*58b9f456SAndroid Build Coastguard Workercondition_variable_any::condition_variable_any()
171*58b9f456SAndroid Build Coastguard Worker    : __mut_(make_shared<mutex>()) {}
172*58b9f456SAndroid Build Coastguard Worker
173*58b9f456SAndroid Build Coastguard Workerinline
174*58b9f456SAndroid Build Coastguard Workervoid
175*58b9f456SAndroid Build Coastguard Workercondition_variable_any::notify_one() _NOEXCEPT
176*58b9f456SAndroid Build Coastguard Worker{
177*58b9f456SAndroid Build Coastguard Worker    {lock_guard<mutex> __lx(*__mut_);}
178*58b9f456SAndroid Build Coastguard Worker    __cv_.notify_one();
179*58b9f456SAndroid Build Coastguard Worker}
180*58b9f456SAndroid Build Coastguard Worker
181*58b9f456SAndroid Build Coastguard Workerinline
182*58b9f456SAndroid Build Coastguard Workervoid
183*58b9f456SAndroid Build Coastguard Workercondition_variable_any::notify_all() _NOEXCEPT
184*58b9f456SAndroid Build Coastguard Worker{
185*58b9f456SAndroid Build Coastguard Worker    {lock_guard<mutex> __lx(*__mut_);}
186*58b9f456SAndroid Build Coastguard Worker    __cv_.notify_all();
187*58b9f456SAndroid Build Coastguard Worker}
188*58b9f456SAndroid Build Coastguard Worker
189*58b9f456SAndroid Build Coastguard Workerstruct __lock_external
190*58b9f456SAndroid Build Coastguard Worker{
191*58b9f456SAndroid Build Coastguard Worker    template <class _Lock>
192*58b9f456SAndroid Build Coastguard Worker    void operator()(_Lock* __m) {__m->lock();}
193*58b9f456SAndroid Build Coastguard Worker};
194*58b9f456SAndroid Build Coastguard Worker
195*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock>
196*58b9f456SAndroid Build Coastguard Workervoid
197*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait(_Lock& __lock)
198*58b9f456SAndroid Build Coastguard Worker{
199*58b9f456SAndroid Build Coastguard Worker    shared_ptr<mutex> __mut = __mut_;
200*58b9f456SAndroid Build Coastguard Worker    unique_lock<mutex> __lk(*__mut);
201*58b9f456SAndroid Build Coastguard Worker    __lock.unlock();
202*58b9f456SAndroid Build Coastguard Worker    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
203*58b9f456SAndroid Build Coastguard Worker    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
204*58b9f456SAndroid Build Coastguard Worker    __cv_.wait(__lk);
205*58b9f456SAndroid Build Coastguard Worker}  // __mut_.unlock(), __lock.lock()
206*58b9f456SAndroid Build Coastguard Worker
207*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Predicate>
208*58b9f456SAndroid Build Coastguard Workerinline
209*58b9f456SAndroid Build Coastguard Workervoid
210*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait(_Lock& __lock, _Predicate __pred)
211*58b9f456SAndroid Build Coastguard Worker{
212*58b9f456SAndroid Build Coastguard Worker    while (!__pred())
213*58b9f456SAndroid Build Coastguard Worker        wait(__lock);
214*58b9f456SAndroid Build Coastguard Worker}
215*58b9f456SAndroid Build Coastguard Worker
216*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Clock, class _Duration>
217*58b9f456SAndroid Build Coastguard Workercv_status
218*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_until(_Lock& __lock,
219*58b9f456SAndroid Build Coastguard Worker                                   const chrono::time_point<_Clock, _Duration>& __t)
220*58b9f456SAndroid Build Coastguard Worker{
221*58b9f456SAndroid Build Coastguard Worker    shared_ptr<mutex> __mut = __mut_;
222*58b9f456SAndroid Build Coastguard Worker    unique_lock<mutex> __lk(*__mut);
223*58b9f456SAndroid Build Coastguard Worker    __lock.unlock();
224*58b9f456SAndroid Build Coastguard Worker    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
225*58b9f456SAndroid Build Coastguard Worker    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
226*58b9f456SAndroid Build Coastguard Worker    return __cv_.wait_until(__lk, __t);
227*58b9f456SAndroid Build Coastguard Worker}  // __mut_.unlock(), __lock.lock()
228*58b9f456SAndroid Build Coastguard Worker
229*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Clock, class _Duration, class _Predicate>
230*58b9f456SAndroid Build Coastguard Workerinline
231*58b9f456SAndroid Build Coastguard Workerbool
232*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_until(_Lock& __lock,
233*58b9f456SAndroid Build Coastguard Worker                                   const chrono::time_point<_Clock, _Duration>& __t,
234*58b9f456SAndroid Build Coastguard Worker                                   _Predicate __pred)
235*58b9f456SAndroid Build Coastguard Worker{
236*58b9f456SAndroid Build Coastguard Worker    while (!__pred())
237*58b9f456SAndroid Build Coastguard Worker        if (wait_until(__lock, __t) == cv_status::timeout)
238*58b9f456SAndroid Build Coastguard Worker            return __pred();
239*58b9f456SAndroid Build Coastguard Worker    return true;
240*58b9f456SAndroid Build Coastguard Worker}
241*58b9f456SAndroid Build Coastguard Worker
242*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Rep, class _Period>
243*58b9f456SAndroid Build Coastguard Workerinline
244*58b9f456SAndroid Build Coastguard Workercv_status
245*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_for(_Lock& __lock,
246*58b9f456SAndroid Build Coastguard Worker                                 const chrono::duration<_Rep, _Period>& __d)
247*58b9f456SAndroid Build Coastguard Worker{
248*58b9f456SAndroid Build Coastguard Worker    return wait_until(__lock, chrono::steady_clock::now() + __d);
249*58b9f456SAndroid Build Coastguard Worker}
250*58b9f456SAndroid Build Coastguard Worker
251*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Rep, class _Period, class _Predicate>
252*58b9f456SAndroid Build Coastguard Workerinline
253*58b9f456SAndroid Build Coastguard Workerbool
254*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_for(_Lock& __lock,
255*58b9f456SAndroid Build Coastguard Worker                                 const chrono::duration<_Rep, _Period>& __d,
256*58b9f456SAndroid Build Coastguard Worker                                 _Predicate __pred)
257*58b9f456SAndroid Build Coastguard Worker{
258*58b9f456SAndroid Build Coastguard Worker    return wait_until(__lock, chrono::steady_clock::now() + __d,
259*58b9f456SAndroid Build Coastguard Worker                      _VSTD::move(__pred));
260*58b9f456SAndroid Build Coastguard Worker}
261*58b9f456SAndroid Build Coastguard Worker
262*58b9f456SAndroid Build Coastguard Worker_LIBCPP_FUNC_VIS
263*58b9f456SAndroid Build Coastguard Workervoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
264*58b9f456SAndroid Build Coastguard Worker
265*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_STD
266*58b9f456SAndroid Build Coastguard Worker
267*58b9f456SAndroid Build Coastguard Worker#endif // !_LIBCPP_HAS_NO_THREADS
268*58b9f456SAndroid Build Coastguard Worker
269*58b9f456SAndroid Build Coastguard Worker#endif  // _LIBCPP_CONDITION_VARIABLE
270