source: mainline/uspace/lib/cpp/include/impl/mutex.hpp@ a97b838

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a97b838 was a97b838, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added missing noexcept specifier

  • Property mode set to 100644
File size: 7.4 KB
RevLine 
[a75f3e49]1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_MUTEX
30#define LIBCPP_MUTEX
31
[5e5498e]32#include <internal/common.hpp>
[9283830]33#include <internal/thread.hpp>
[a75f3e49]34#include <thread>
35
36namespace std
37{
38 /**
39 * 20.4.1.2.1, class mutex:
40 */
41
42 class mutex
43 {
44 public:
[9283830]45 constexpr mutex() noexcept
46 : mtx_{}
47 {
48 aux::threading::mutex::init(mtx_);
49 }
50
[a75f3e49]51 ~mutex();
52
53 mutex(const mutex&) = delete;
54 mutex& operator=(const mutex&) = delete;
55
56 void lock();
57 bool try_lock();
58 void unlock();
59
[9283830]60 using native_handle_type = aux::mutex_t*;
[a75f3e49]61 native_handle_type native_handle();
62
63 private:
[9283830]64 aux::mutex_t mtx_;
[a75f3e49]65 };
66
67 /**
68 * 30.4.1.2.2, class recursive_mutex:
69 */
70
71 class recursive_mutex
72 {
73 public:
[69e5838]74 constexpr recursive_mutex() noexcept
75 : mtx_{}, lock_level_{}, owner_{}
76 {
77 aux::threading::mutex::init(mtx_);
78 }
79
[a75f3e49]80 ~recursive_mutex();
81
82 recursive_mutex(const recursive_mutex&) = delete;
83 recursive_mutex& operator=(const recursive_mutex&) = delete;
84
85 void lock();
[857d4cc]86 bool try_lock() noexcept;
[a75f3e49]87 void unlock();
88
[9283830]89 using native_handle_type = aux::mutex_t*;
[a75f3e49]90 native_handle_type native_handle();
91
92 private:
[9283830]93 aux::mutex_t mtx_;
[a75f3e49]94 size_t lock_level_;
95 thread::id owner_;
96 };
97
98 /**
99 * 30.4.1.3.1, class timed_mutex:
100 */
101
[69e5838]102 class timed_mutex
103 {
104 public:
105 timed_mutex() noexcept;
106 ~timed_mutex();
107
108 timed_mutex(const timed_mutex&) = delete;
109 timed_mutex& operator=(const timed_mutex&) = delete;
110
111 void lock();
112 bool try_lock();
113 void unlock();
114
115 template<class Rep, class Period>
116 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
117 {
118 auto time = aux::threading::time::convert(rel_time);
119
120 return aux::threading::mutex::try_lock_for(time);
121 }
122
123 template<class Clock, class Duration>
124 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
125 {
126 auto dur = (abs_time - Clock::now());
127 auto time = aux::threading::time::convert(dur);
128
129 return aux::threading::mutex::try_lock_for(time);
130 }
131
132 using native_handle_type = aux::mutex_t*;
133 native_handle_type native_handle();
134
135 private:
136 aux::mutex_t mtx_;
137 };
[a75f3e49]138
139 /**
140 * 30.4.1.3.2, class recursive_timed_mutex:
141 */
142
[857d4cc]143 class recursive_timed_mutex
144 {
145 public:
146 recursive_timed_mutex() noexcept
147 : mtx_{}, lock_level_{}, owner_{}
148 {
149 aux::threading::mutex::init(mtx_);
150 }
151
152 ~recursive_timed_mutex();
153
154 recursive_timed_mutex(const recursive_timed_mutex&) = delete;
155 recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
156
157 void lock();
[a97b838]158 bool try_lock() noexcept;
[857d4cc]159 void unlock();
160
161 template<class Rep, class Period>
162 bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
163 {
164 if (owner_ == this_thread::get_id())
165 return true;
166
167 auto time = aux::threading::time::convert(rel_time);
168 auto ret = aux::threading::mutex::try_lock_for(time);
169
170 if (ret)
171 ++lock_level_;
172 return ret;
173 }
174
175 template<class Clock, class Duration>
176 bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
177 {
178 if (owner_ == this_thread::get_id())
179 return true;
180
181 auto dur = (abs_time - Clock::now());
182 auto time = aux::threading::time::convert(dur);
183 auto ret = aux::threading::mutex::try_lock_for(time);
184
185 if (ret)
186 ++lock_level_;
187 return ret;
188 }
189
190 using native_handle_type = aux::mutex_t*;
191 native_handle_type native_handle();
192
193 private:
194 aux::mutex_t mtx_;
195 size_t lock_level_;
196 thread::id owner_;
197 };
[a75f3e49]198
199 struct defer_lock_t
200 { /* DUMMY BODY */ };
201
202 struct try_to_lock_t
203 { /* DUMMY BODY */ };
204
205 struct adopt_lock_t
206 { /* DUMMY BODY */ };
207
208 constexpr defer_lock_t defer_lock
209 { /* DUMMY BODY */ };
210
211 constexpr try_to_lock_t try_to_lock
212 { /* DUMMY BODY */ };
213
214 constexpr adopt_lock_t adopt_lock
215 { /* DUMMY BODY */ };
216
217 /**
218 * 30.4.2.1, class template lock_guard:
219 */
220
221 template<class Mutex>
222 class lock_guard
223 {
224 public:
225 using mutex_type = Mutex;
226
227 explicit lock_guard(mutex_type& mtx)
228 : mtx_{mtx}
229 {
230 mtx.lock();
231 }
232
233 lock_guard(mutex_type& mtx, adopt_lock_t)
234 : mtx_{mtx}
235 { /* DUMMY BODY */ }
236
237 ~lock_guard()
238 {
239 mtx_.unlock();
240 }
241
242 lock_guard(const lock_guard&) = delete;
243 lock_guard& operator=(const lock_guard&) = delete;
244
245 private:
246 mutex_type& mtx_;
247 };
248
249 template<class Mutex>
250 class unique_lock;
251
252 template<class Mutex>
253 void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs) noexcept;
254
255 template<class L1, class L2, class... L3>
256 int try_lock(L1& l1, L2& l2, L3&... ls);
257
258 template<class L1, class L2, class... L3>
259 void lock(L1& l1, L2& l2, L3&... ls);
260
261 struct once_flag
262 {
263 constexpr once_flag() noexcept;
264
265 once_flag(const once_flag&) = delete;
266 once_flag& operator=(const once_flag&) = delete;
267 };
268
269 template<class Callable, class... Args>
270 void call_once(once_flag& flag, Callable&& func, Args&&... args);
271}
272
273#endif
Note: See TracBrowser for help on using the repository browser.