Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / c++ / condition_variable

History | View | Annotate | Download (7.26 KB)

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