Coverage Report

Created: 2020-02-25 14:32

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