µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
mutex
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2016-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13/*
14 * The code is inspired by LLVM libcxx and GNU libstdc++-v3.
15 */
16
17#ifndef CMSIS_PLUS_ESTD_MUTEX_
18#define CMSIS_PLUS_ESTD_MUTEX_
19
20// ----------------------------------------------------------------------------
21
22// Include the next <mutex> file found in the search path.
23#pragma GCC diagnostic push
24#if defined(__clang__)
25#pragma clang diagnostic ignored "-Wgnu-include-next"
26#endif
27#include_next <mutex>
28#pragma GCC diagnostic pop
29
30#include <tuple>
31#include <cerrno>
32
33#include <cmsis-plus/rtos/os.h>
34
37
38// ----------------------------------------------------------------------------
39
40#pragma GCC diagnostic push
41#if defined(__clang__)
42#pragma clang diagnostic ignored "-Wc++98-compat"
43#endif
44
45// ----------------------------------------------------------------------------
46
47namespace os
48{
49 namespace estd
50 {
51 // ------------------------------------------------------------------------
52
58 // ========================================================================
59 class mutex
60 {
61 private:
62
64
65 public:
66
68
69 /* constexpr in ISO */
70 mutex () noexcept;
71
72 ~mutex () = default;
73
74 mutex (const mutex&) = delete;
75 mutex&
76 operator= (const mutex&) = delete;
77
78 void
79 lock ();
80
81 bool
82 try_lock ();
83
84 void
85 unlock ();
86
89
90 protected:
91
93 };
94
95 // ========================================================================
96
98 {
99 private:
100
102
103 public:
104
106
108
109 ~recursive_mutex () = default;
110
113 operator= (const recursive_mutex&) = delete;
114
115 void
116 lock ();
117
118 bool
119 try_lock () noexcept;
120
121 void
122 unlock ();
123
125 native_handle ();
126
127 protected:
128
130 };
131
132 // ========================================================================
133
134 class timed_mutex : public mutex
135 {
136 public:
137
138 timed_mutex () = default;
139
140 ~timed_mutex () = default;
141
142 timed_mutex (const timed_mutex&) = delete;
144 operator= (const timed_mutex&) = delete;
145
146 template<typename Rep_T, typename Period_T>
147 bool
148 try_lock_for (const std::chrono::duration<Rep_T, Period_T>& rel_time);
149
150 template<typename Clock_T, typename Duration_T>
151 bool
152 try_lock_until (
153 const std::chrono::time_point<Clock_T, Duration_T>& abs_time);
154 };
155
156 // ========================================================================
157
159 {
160 public:
161
163
165
168 operator= (const recursive_timed_mutex&) = delete;
169
170 template<typename Rep_T, typename Period_T>
171 bool
172 try_lock_for (const std::chrono::duration<Rep_T, Period_T>& rel_time);
173
174 template<typename Clock_T, typename Duration_T>
175 bool
176 try_lock_until (
177 const std::chrono::time_point<Clock_T, Duration_T>& abs_time);
178 };
179
184 // ========================================================================
185 // Inline & template implementations.
186 // ========================================================================
187 inline
188 mutex::mutex () noexcept
189 {
190 }
191
194 {
195 return &nm_;
196 }
197
198 // ========================================================================
199
200 inline
202 nm_
204 {
205 }
206
209 {
210 return &nm_;
211 }
212
213 // ========================================================================
214
215#pragma GCC diagnostic push
216#if defined(__clang__)
217#elif defined(__GNUC__)
218#pragma GCC diagnostic ignored "-Waggregate-return"
219#endif
220
221 template<typename Rep_T, typename Period_T>
222 bool
224 const std::chrono::duration<Rep_T, Period_T>& rel_time)
225 {
226 using namespace std::chrono;
228 if (rel_time > duration<Rep_T, Period_T>::zero ())
229 {
230 ticks =
232 os::estd::chrono::systicks> (rel_time).count ());
233 }
234
236 res = nm_.timed_lock (ticks);
237 if (res == os::rtos::result::ok)
238 {
239 return true;
240 }
241 else if (res == ETIMEDOUT)
242 {
243 return false;
244 }
245
246 os::estd::__throw_system_error (static_cast<int> (res),
247 "timed_mutex try_lock failed");
248 return false;
249 }
250
251 template<typename Clock_T, typename Duration_T>
252 bool
254 const std::chrono::time_point<Clock_T, Duration_T>& abs_time)
255 {
256 using clock = Clock_T;
257
258 auto now = clock::now ();
259 while (now < abs_time)
260 {
261 if (try_lock_for (abs_time - now))
262 {
263 return true;
264 }
265 now = clock::now ();
266 }
267
268 return false;
269 }
270
271#pragma GCC diagnostic pop
272
273 // ========================================================================
274
275 template<typename Rep_T, typename Period_T>
276 bool
278 const std::chrono::duration<Rep_T, Period_T>& rel_time)
279 {
280 using namespace std::chrono;
282 if (rel_time > duration<Rep_T, Period_T>::zero ())
283 {
284 ticks =
286 os::estd::chrono::systicks> (rel_time).count ());
287 }
288
290 res = nm_.timed_lock (ticks);
291 if (res == os::rtos::result::ok)
292 {
293 return true;
294 }
295 else if (res == ETIMEDOUT)
296 {
297 return false;
298 }
299
300 os::estd::__throw_system_error (static_cast<int> (res),
301 "timed_mutex try_lock failed");
302 return false;
303 }
304
305 template<typename Clock_T, typename Duration_T>
306 bool
308 const std::chrono::time_point<Clock_T, Duration_T>& abs_time)
309 {
310 using clock = Clock_T;
311
312 auto now = clock::now ();
313 while (now < abs_time)
314 {
315 if (try_lock_for (abs_time - now))
316 {
317 return true;
318 }
319 now = clock::now ();
320 }
321
322 return false;
323 }
324
325 // ==========================================================================
326 } /* namespace estd */
327} /* namespace os */
328
329#pragma GCC diagnostic pop
330
331#if defined(OS_HAS_STD_THREADS)
332
333namespace std
334{
340 // Redefine the objects in the std:: namespace.
341
342 using mutex = os::estd::mutex;
343 using recursive_mutex = os::estd::recursive_mutex;
344 using timed_mutex = os::estd::timed_mutex;
345 using recursive_timed_mutex = os::estd::recursive_timed_mutex;
346
350}
351
352#endif
353
354// ----------------------------------------------------------------------------
355
356#endif /* CMSIS_PLUS_ESTD_MUTEX_ */
native_type nm_
Definition mutex:92
mutex() noexcept
Definition mutex:188
mutex & operator=(const mutex &)=delete
void lock()
Definition mutex.cpp:30
native_handle_type native_handle()
Definition mutex:193
bool try_lock()
Definition mutex.cpp:42
void unlock()
Definition mutex.cpp:61
recursive_mutex(const recursive_mutex &)=delete
native_type nm_
Definition mutex:129
native_type * native_handle_type
Definition mutex:105
native_handle_type native_handle()
Definition mutex:208
recursive_timed_mutex(const recursive_timed_mutex &)=delete
bool try_lock_for(const std::chrono::duration< Rep_T, Period_T > &rel_time)
Definition mutex:277
bool try_lock_until(const std::chrono::time_point< Clock_T, Duration_T > &abs_time)
Definition mutex:307
bool try_lock_for(const std::chrono::duration< Rep_T, Period_T > &rel_time)
Definition mutex:223
bool try_lock_until(const std::chrono::time_point< Clock_T, Duration_T > &abs_time)
Definition mutex:253
timed_mutex(const timed_mutex &)=delete
POSIX compliant mutex.
Definition os-mutex.h:53
result_t timed_lock(clock::duration_t timeout)
Timed attempt to lock/acquire the mutex.
clock_t clock(void)
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:76
static const attributes_recursive initializer_recursive
Default recursive mutex initialiser.
Definition os-mutex.h:350
systick_clock::duration systicks
Definition chrono:101
constexpr std::enable_if< std::chrono::__is_duration< _To >::value, _To >::type ceil(std::chrono::duration< Rep_T, Period_T > d)
Definition chrono:269
void __throw_system_error(int ev, const char *what_arg)
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:181
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:96
System namespace.
Standard std namespace.
Single file µOS++ RTOS definitions.