source: mainline/uspace/lib/cpp/include/__bits/thread/condition_variable.hpp@ c6f23a7

Last change on this file since c6f23a7 was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_BITS_THREAD_CONDITION_VARIABLE
8#define LIBCPP_BITS_THREAD_CONDITION_VARIABLE
9
10#include <__bits/thread/threading.hpp>
11#include <mutex>
12
13namespace std
14{
15 enum class cv_status
16 {
17 no_timeout,
18 timeout
19 };
20
21 namespace aux
22 {
23 template<class Clock, class Duration>
24 aux::time_unit_t time_until(const chrono::time_point<Clock, Duration>& abs_time)
25 {
26 return aux::threading::time::convert(abs_time - Clock::now());
27 }
28 }
29
30 /**
31 * 30.5.1, class condition_variable:
32 */
33
34 class condition_variable
35 {
36 public:
37 condition_variable();
38 ~condition_variable();
39
40 condition_variable(const condition_variable&) = delete;
41 condition_variable& operator=(const condition_variable&) = delete;
42
43 void notify_one() noexcept;
44 void notify_all() noexcept;
45
46 void wait(unique_lock<mutex>&);
47
48 template<class Predicate>
49 void wait(unique_lock<mutex>& lock, Predicate pred)
50 {
51 /**
52 * Note: lock is supposed to be locked here,
53 * so no need to lock it.
54 */
55 while (!pred())
56 wait(lock);
57 }
58
59 template<class Clock, class Duration>
60 cv_status wait_until(unique_lock<mutex>& lock,
61 const chrono::time_point<Clock, Duration>& abs_time)
62 {
63 auto ret = aux::threading::condvar::wait_for(
64 cv_, *lock.mutex()->native_handle(), aux::time_until(abs_time)
65 );
66
67 if (ret == EOK)
68 return cv_status::no_timeout;
69 else
70 return cv_status::timeout;
71 }
72
73 template<class Clock, class Duration, class Predicate>
74 bool wait_until(unique_lock<mutex>& lock,
75 const chrono::time_point<Clock, Duration>& abs_time,
76 Predicate pred)
77 {
78 while (!pred())
79 {
80 if (wait_until(lock, abs_time) == cv_status::timeout)
81 return pred();
82 }
83
84 return true;
85 }
86
87 template<class Rep, class Period>
88 cv_status wait_for(unique_lock<mutex>& lock,
89 const chrono::duration<Rep, Period>& rel_time)
90 {
91 return wait_until(
92 lock, chrono::steady_clock::now() + rel_time
93 );
94 }
95
96 template<class Rep, class Period, class Predicate>
97 bool wait_for(unique_lock<mutex>& lock,
98 const chrono::duration<Rep, Period>& rel_time,
99 Predicate pred)
100 {
101 return wait_until(
102 lock, chrono::steady_clock::now() + rel_time,
103 move(pred)
104 );
105 }
106
107 using native_handle_type = aux::condvar_t*;
108 native_handle_type native_handle();
109
110 private:
111 aux::condvar_t cv_;
112 };
113
114 /**
115 * 30.5.2, class condition_variable_any:
116 */
117
118 class condition_variable_any
119 {
120 public:
121 condition_variable_any();
122 ~condition_variable_any();
123
124 condition_variable_any(const condition_variable_any&) = delete;
125 condition_variable_any& operator=(const condition_variable_any&) = delete;
126
127 void notify_one() noexcept;
128 void notify_all() noexcept;
129
130 template<class Lock>
131 void wait(Lock& lock)
132 {
133 aux::threading::condvar::wait(cv_, *lock.native_handle());
134 }
135
136 template<class Lock, class Predicate>
137 void wait(Lock& lock, Predicate pred)
138 {
139 while (!pred())
140 wait(lock);
141 }
142
143 template<class Lock, class Clock, class Duration>
144 cv_status wait_until(Lock& lock,
145 const chrono::time_point<Clock, Duration>& abs_time)
146 {
147 auto ret = aux::threading::condvar::wait_for(
148 cv_, *lock.mutex()->native_handle(), aux::time_until(abs_time)
149 );
150
151 if (ret == EOK)
152 return cv_status::no_timeout;
153 else
154 return cv_status::timeout;
155 }
156
157 template<class Lock, class Clock, class Duration, class Predicate>
158 bool wait_until(Lock& lock,
159 const chrono::time_point<Clock, Duration>& abs_time,
160 Predicate pred)
161 {
162 while (!pred())
163 {
164 if (wait_until(lock, abs_time) == cv_status::timeout)
165 return pred();
166 }
167
168 return true;
169 }
170
171 template<class Lock, class Rep, class Period>
172 cv_status wait_for(Lock& lock,
173 const chrono::duration<Rep, Period>& rel_time)
174 {
175 return wait_until(
176 lock, chrono::steady_clock::now() + rel_time
177 );
178 }
179
180 template<class Lock, class Rep, class Period, class Predicate>
181 bool wait_for(Lock& lock,
182 const chrono::duration<Rep, Period>& rel_time,
183 Predicate pred)
184 {
185 return wait_until(
186 lock, chrono::steady_clock::now() + rel_time,
187 move(pred)
188 );
189 }
190
191 using native_handle_type = aux::condvar_t*;
192 native_handle_type native_handle();
193
194 private:
195 aux::condvar_t cv_;
196 };
197
198 void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>&);
199}
200
201#endif
Note: See TracBrowser for help on using the repository browser.