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