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