]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/condition_variable
PR libstdc++/36104 part four
[thirdparty/gcc.git] / libstdc++-v3 / include / std / condition_variable
CommitLineData
68a97d24
BK
1// <condition_variable> -*- C++ -*-
2
cdf5f5a3 3// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
68a97d24
BK
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
748086b7 8// Free Software Foundation; either version 3, or (at your option)
68a97d24
BK
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
748086b7
JJ
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
68a97d24 19
748086b7
JJ
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
68a97d24 24
f910786b 25/** @file include/condition_variable
68a97d24
BK
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_CONDITION_VARIABLE
30#define _GLIBCXX_CONDITION_VARIABLE 1
31
32#pragma GCC system_header
33
34#ifndef __GXX_EXPERIMENTAL_CXX0X__
ab65a4c7 35# include <bits/c++0x_warning.h>
57317d2a 36#else
68a97d24 37
7b800287 38#include <chrono>
68a97d24
BK
39#include <mutex> // unique_lock
40
7b800287
CF
41#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
42
12ffa228
BK
43namespace std _GLIBCXX_VISIBILITY(default)
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
53dc5044 46
5b9daa7e
BK
47 /**
48 * @defgroup condition_variables Condition Variables
49 * @ingroup concurrency
50 *
51 * Classes for condition_variable support.
52 * @{
53 */
54
cdf5f5a3
PC
55 /// cv_status
56 enum class cv_status { no_timeout, timeout };
57
68a97d24
BK
58 /// condition_variable
59 class condition_variable
60 {
f7459b6c
BK
61 typedef chrono::system_clock __clock_t;
62 typedef __gthread_cond_t __native_type;
63 __native_type _M_cond;
88399079 64
68a97d24 65 public:
f7459b6c 66 typedef __native_type* native_handle_type;
68a97d24 67
50a681c4
JH
68 condition_variable() throw ();
69 ~condition_variable() throw ();
68a97d24 70
7b800287
CF
71 condition_variable(const condition_variable&) = delete;
72 condition_variable& operator=(const condition_variable&) = delete;
73
d5cf2021 74 void
68a97d24
BK
75 notify_one();
76
d5cf2021 77 void
68a97d24
BK
78 notify_all();
79
d5cf2021 80 void
68a97d24
BK
81 wait(unique_lock<mutex>& __lock);
82
83 template<typename _Predicate>
d5cf2021 84 void
68a97d24
BK
85 wait(unique_lock<mutex>& __lock, _Predicate __p)
86 {
87 while (!__p())
88 wait(__lock);
89 }
d5cf2021 90
88399079 91 template<typename _Duration>
cdf5f5a3 92 cv_status
88399079
CF
93 wait_until(unique_lock<mutex>& __lock,
94 const chrono::time_point<__clock_t, _Duration>& __atime)
95 { return __wait_until_impl(__lock, __atime); }
96
97 template<typename _Clock, typename _Duration>
cdf5f5a3 98 cv_status
88399079 99 wait_until(unique_lock<mutex>& __lock,
7b800287
CF
100 const chrono::time_point<_Clock, _Duration>& __atime)
101 {
88399079 102 // DR 887 - Sync unknown clock to known clock.
023cee96
PC
103 const typename _Clock::time_point __c_entry = _Clock::now();
104 const __clock_t::time_point __s_entry = __clock_t::now();
105 const chrono::nanoseconds __delta = __atime - __c_entry;
106 const __clock_t::time_point __s_atime = __s_entry + __delta;
7b800287 107
88399079 108 return __wait_until_impl(__lock, __s_atime);
7b800287 109 }
d3098c94
CF
110
111 template<typename _Clock, typename _Duration, typename _Predicate>
112 bool
113 wait_until(unique_lock<mutex>& __lock,
114 const chrono::time_point<_Clock, _Duration>& __atime,
88399079
CF
115 _Predicate __p)
116 {
f7459b6c 117 while (!__p())
cdf5f5a3 118 if (wait_until(__lock, __atime) == cv_status::timeout)
88399079 119 return __p();
88399079
CF
120 return true;
121 }
d3098c94
CF
122
123 template<typename _Rep, typename _Period>
cdf5f5a3 124 cv_status
d3098c94 125 wait_for(unique_lock<mutex>& __lock,
7b800287 126 const chrono::duration<_Rep, _Period>& __rtime)
88399079 127 { return wait_until(__lock, __clock_t::now() + __rtime); }
d3098c94
CF
128
129 template<typename _Rep, typename _Period, typename _Predicate>
130 bool
131 wait_for(unique_lock<mutex>& __lock,
132 const chrono::duration<_Rep, _Period>& __rtime,
88399079
CF
133 _Predicate __p)
134 { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
68a97d24 135
d5cf2021
BK
136 native_handle_type
137 native_handle()
7b800287 138 { return &_M_cond; }
68a97d24
BK
139
140 private:
88399079 141 template<typename _Clock, typename _Duration>
cdf5f5a3 142 cv_status
88399079
CF
143 __wait_until_impl(unique_lock<mutex>& __lock,
144 const chrono::time_point<_Clock, _Duration>& __atime)
145 {
146 chrono::time_point<__clock_t, chrono::seconds> __s =
d5cf2021
BK
147 chrono::time_point_cast<chrono::seconds>(__atime);
148
88399079 149 chrono::nanoseconds __ns =
d5cf2021
BK
150 chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
151
152 __gthread_time_t __ts =
153 {
154 static_cast<std::time_t>(__s.time_since_epoch().count()),
155 static_cast<long>(__ns.count())
156 };
157
158 __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(),
159 &__ts);
160
cdf5f5a3
PC
161 return (_Clock::now() < __atime
162 ? cv_status::no_timeout : cv_status::timeout);
88399079 163 }
68a97d24
BK
164 };
165
166 /// condition_variable_any
b7200e3f 167 // Like above, but mutex is not required to have try_lock.
68a97d24
BK
168 class condition_variable_any
169 {
b7200e3f
JW
170 typedef chrono::system_clock __clock_t;
171 condition_variable _M_cond;
172 mutex _M_mutex;
f7459b6c 173
68a97d24 174 public:
b7200e3f 175 typedef condition_variable::native_handle_type native_handle_type;
68a97d24 176
50a681c4
JH
177 condition_variable_any() throw ();
178 ~condition_variable_any() throw ();
d5cf2021 179
7b800287
CF
180 condition_variable_any(const condition_variable_any&) = delete;
181 condition_variable_any& operator=(const condition_variable_any&) = delete;
68a97d24 182
d5cf2021 183 void
b7200e3f
JW
184 notify_one()
185 {
186 lock_guard<mutex> __lock(_M_mutex);
187 _M_cond.notify_one();
188 }
68a97d24 189
d5cf2021 190 void
b7200e3f
JW
191 notify_all()
192 {
193 lock_guard<mutex> __lock(_M_mutex);
194 _M_cond.notify_all();
195 }
68a97d24
BK
196
197 template<typename _Lock>
d5cf2021 198 void
b7200e3f
JW
199 wait(_Lock& __lock)
200 {
201 unique_lock<mutex> __my_lock(_M_mutex);
202 __lock.unlock();
203 _M_cond.wait(__my_lock);
204 __lock.lock();
205 }
206
68a97d24
BK
207
208 template<typename _Lock, typename _Predicate>
d5cf2021 209 void
cdf5f5a3
PC
210 wait(_Lock& __lock, _Predicate __p)
211 {
212 while (!__p())
213 wait(__lock);
214 }
68a97d24 215
d3098c94 216 template<typename _Lock, typename _Clock, typename _Duration>
cdf5f5a3 217 cv_status
d3098c94 218 wait_until(_Lock& __lock,
b7200e3f
JW
219 const chrono::time_point<_Clock, _Duration>& __atime)
220 {
221 unique_lock<mutex> __my_lock(_M_mutex);
222 __lock.unlock();
223 cv_status __status = _M_cond.wait_until(__my_lock, __atime);
224 __lock.lock();
225 return __status;
226 }
68a97d24 227
d5cf2021 228 template<typename _Lock, typename _Clock,
d3098c94 229 typename _Duration, typename _Predicate>
d5cf2021 230 bool
d3098c94
CF
231 wait_until(_Lock& __lock,
232 const chrono::time_point<_Clock, _Duration>& __atime,
cdf5f5a3
PC
233 _Predicate __p)
234 {
235 while (!__p())
236 if (wait_until(__lock, __atime) == cv_status::timeout)
237 return __p();
238 return true;
239 }
d5cf2021 240
d3098c94 241 template<typename _Lock, typename _Rep, typename _Period>
cdf5f5a3 242 cv_status
b7200e3f
JW
243 wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime)
244 { return wait_until(__lock, __clock_t::now() + __rtime); }
d3098c94
CF
245
246 template<typename _Lock, typename _Rep,
247 typename _Period, typename _Predicate>
248 bool
d5cf2021 249 wait_for(_Lock& __lock,
b7200e3f
JW
250 const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p)
251 { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
68a97d24 252
d5cf2021 253 native_handle_type
7b800287 254 native_handle()
b7200e3f 255 { return _M_cond.native_handle(); }
68a97d24 256 };
5b9daa7e
BK
257
258 // @} group condition_variables
12ffa228
BK
259_GLIBCXX_END_NAMESPACE_VERSION
260} // namespace
68a97d24 261
7b800287
CF
262#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
263
57317d2a
PC
264#endif // __GXX_EXPERIMENTAL_CXX0X__
265
266#endif // _GLIBCXX_CONDITION_VARIABLE