µ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++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2016-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12/*
13 * The code is inspired by LLVM libcxx and GNU libstdc++-v3.
14 */
15
16#ifndef CMSIS_PLUS_ESTD_MUTEX_
17#define CMSIS_PLUS_ESTD_MUTEX_
18
19// ----------------------------------------------------------------------------
20
21// Include the next <mutex> file found in the search path.
22#pragma GCC diagnostic push
23#if defined(__clang__)
24#pragma clang diagnostic ignored "-Wgnu-include-next"
25#endif
26#include_next <mutex>
27#pragma GCC diagnostic pop
28
29#include <tuple>
30#include <cerrno>
31
32#include <cmsis-plus/rtos/os.h>
33
36
37// ----------------------------------------------------------------------------
38
39#pragma GCC diagnostic push
40#if defined(__clang__)
41#pragma clang diagnostic ignored "-Wc++98-compat"
42#endif
43
44// ----------------------------------------------------------------------------
45
46namespace os
47{
48 namespace estd
49 {
50 // ------------------------------------------------------------------------
51
57 // ========================================================================
58 class mutex
59 {
60 private:
62
63 public:
65
66 /* constexpr in ISO */
67 mutex () noexcept;
68
69 ~mutex () = default;
70
71 mutex (const mutex&) = delete;
72 mutex&
73 operator= (const mutex&)
74 = delete;
75
76 void
77 lock ();
78
79 bool
80 try_lock ();
81
82 void
83 unlock ();
84
87
88 protected:
90 };
91
92 // ========================================================================
93
95 {
96 private:
98
99 public:
101
103
104 ~recursive_mutex () = default;
105
109 = delete;
110
111 void
112 lock ();
113
114 bool
115 try_lock () noexcept;
116
117 void
118 unlock ();
119
121 native_handle ();
122
123 protected:
125 };
126
127 // ========================================================================
128
129 class timed_mutex : public mutex
130 {
131 public:
132 timed_mutex () = default;
133
134 ~timed_mutex () = default;
135
136 timed_mutex (const timed_mutex&) = delete;
139 = delete;
140
141 template <typename Rep_T, typename Period_T>
142 bool
143 try_lock_for (const std::chrono::duration<Rep_T, Period_T>& rel_time);
144
145 template <typename Clock_T, typename Duration_T>
146 bool
147 try_lock_until (
148 const std::chrono::time_point<Clock_T, Duration_T>& abs_time);
149 };
150
151 // ========================================================================
152
154 {
155 public:
157
159
162 operator= (const recursive_timed_mutex&)
163 = delete;
164
165 template <typename Rep_T, typename Period_T>
166 bool
167 try_lock_for (const std::chrono::duration<Rep_T, Period_T>& rel_time);
168
169 template <typename Clock_T, typename Duration_T>
170 bool
171 try_lock_until (
172 const std::chrono::time_point<Clock_T, Duration_T>& abs_time);
173 };
174
179 // ========================================================================
180 // Inline & template implementations.
181 // ========================================================================
182 inline mutex::mutex () noexcept
183 {
184 }
185
188 {
189 return &nm_;
190 }
191
192 // ========================================================================
193
195 : nm_{ os::rtos::mutex::initializer_recursive }
196 {
197 }
198
201 {
202 return &nm_;
203 }
204
205 // ========================================================================
206
207#pragma GCC diagnostic push
208#if defined(__clang__)
209#elif defined(__GNUC__)
210#pragma GCC diagnostic ignored "-Waggregate-return"
211#endif
212
213 template <typename Rep_T, typename Period_T>
214 bool
216 const std::chrono::duration<Rep_T, Period_T>& rel_time)
217 {
218 using namespace std::chrono;
220 if (rel_time > duration<Rep_T, Period_T>::zero ())
221 {
222 ticks = static_cast<os::rtos::clock::duration_t> (
223 os::estd::chrono::ceil<os::estd::chrono::systicks> (rel_time)
224 .count ());
225 }
226
228 res = nm_.timed_lock (ticks);
229 if (res == os::rtos::result::ok)
230 {
231 return true;
232 }
233 else if (res == ETIMEDOUT)
234 {
235 return false;
236 }
237
238 os::estd::__throw_system_error (static_cast<int> (res),
239 "timed_mutex try_lock failed");
240 return false;
241 }
242
243 template <typename Clock_T, typename Duration_T>
244 bool
246 const std::chrono::time_point<Clock_T, Duration_T>& abs_time)
247 {
248 using clock = Clock_T;
249
250 auto now = clock::now ();
251 while (now < abs_time)
252 {
253 if (try_lock_for (abs_time - now))
254 {
255 return true;
256 }
257 now = clock::now ();
258 }
259
260 return false;
261 }
262
263#pragma GCC diagnostic pop
264
265 // ========================================================================
266
267 template <typename Rep_T, typename Period_T>
268 bool
270 const std::chrono::duration<Rep_T, Period_T>& rel_time)
271 {
272 using namespace std::chrono;
274 if (rel_time > duration<Rep_T, Period_T>::zero ())
275 {
276 ticks = static_cast<os::rtos::clock::duration_t> (
277 os::estd::chrono::ceil<os::estd::chrono::systicks> (rel_time)
278 .count ());
279 }
280
282 res = nm_.timed_lock (ticks);
283 if (res == os::rtos::result::ok)
284 {
285 return true;
286 }
287 else if (res == ETIMEDOUT)
288 {
289 return false;
290 }
291
292 os::estd::__throw_system_error (static_cast<int> (res),
293 "timed_mutex try_lock failed");
294 return false;
295 }
296
297 template <typename Clock_T, typename Duration_T>
298 bool
300 const std::chrono::time_point<Clock_T, Duration_T>& abs_time)
301 {
302 using clock = Clock_T;
303
304 auto now = clock::now ();
305 while (now < abs_time)
306 {
307 if (try_lock_for (abs_time - now))
308 {
309 return true;
310 }
311 now = clock::now ();
312 }
313
314 return false;
315 }
316
317 // ========================================================================
318 } /* namespace estd */
319} /* namespace os */
320
321#pragma GCC diagnostic pop
322
323#if defined(OS_HAS_STD_THREADS)
324
325namespace std
326{
332 // Redefine the objects in the std:: namespace.
333
334 using mutex = os::estd::mutex;
335 using recursive_mutex = os::estd::recursive_mutex;
336 using timed_mutex = os::estd::timed_mutex;
337 using recursive_timed_mutex = os::estd::recursive_timed_mutex;
338
342} // namespace std
343
344#endif
345
346// ----------------------------------------------------------------------------
347
348#endif /* CMSIS_PLUS_ESTD_MUTEX_ */
native_type nm_
Definition mutex:89
mutex() noexcept
Definition mutex:182
mutex & operator=(const mutex &)=delete
void lock()
Definition mutex.cpp:29
native_handle_type native_handle()
Definition mutex:187
bool try_lock()
Definition mutex.cpp:41
void unlock()
Definition mutex.cpp:60
recursive_mutex(const recursive_mutex &)=delete
native_type nm_
Definition mutex:124
native_handle_type native_handle()
Definition mutex:200
recursive_timed_mutex(const recursive_timed_mutex &)=delete
bool try_lock_for(const std::chrono::duration< Rep_T, Period_T > &rel_time)
Definition mutex:269
bool try_lock_until(const std::chrono::time_point< Clock_T, Duration_T > &abs_time)
Definition mutex:299
bool try_lock_for(const std::chrono::duration< Rep_T, Period_T > &rel_time)
Definition mutex:215
bool try_lock_until(const std::chrono::time_point< Clock_T, Duration_T > &abs_time)
Definition mutex:245
timed_mutex(const timed_mutex &)=delete
POSIX compliant mutex.
Definition os-mutex.h:52
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:78
void __throw_system_error(int ev, const char *what_arg)
@ ok
Function completed; no errors or events occurred.
Definition os-decls.h:179
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:95
System namespace.
Standard std namespace.
Single file µOS++ RTOS definitions.