Skip to content

Commit 2c4e590

Browse files
committed
Add Chrono support to Mutex
1 parent 53cfe0f commit 2c4e590

File tree

2 files changed

+63
-9
lines changed

2 files changed

+63
-9
lines changed

rtos/Mutex.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "rtos/mbed_rtos_types.h"
2828
#include "rtos/mbed_rtos1_types.h"
2929
#include "rtos/mbed_rtos_storage.h"
30+
#include "rtos/Kernel.h"
3031

3132
#include "platform/NonCopyable.h"
3233
#include "platform/ScopedLock.h"
@@ -105,9 +106,23 @@ class Mutex : private mbed::NonCopyable<Mutex> {
105106
the lock attempt will time out earlier than specified.
106107
107108
@note You cannot call this function from ISR context.
109+
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
108110
*/
111+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
109112
bool trylock_for(uint32_t millisec);
110113

114+
/** Try to lock the mutex for a specified time
115+
@param rel_time timeout value.
116+
@return true if the mutex was acquired, false otherwise.
117+
@note the underlying RTOS may have a limit to the maximum wait time
118+
due to internal 32-bit computations, but this is guaranteed to work if the
119+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
120+
the lock attempt will time out earlier than specified.
121+
122+
@note You cannot call this function from ISR context.
123+
*/
124+
bool trylock_for(Kernel::Clock::duration_u32 rel_time);
125+
111126
/** Try to lock the mutex until specified time
112127
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
113128
@return true if the mutex was acquired, false otherwise.
@@ -117,9 +132,24 @@ class Mutex : private mbed::NonCopyable<Mutex> {
117132
the lock attempt will time out earlier than specified.
118133
119134
@note You cannot call this function from ISR context.
135+
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use
136+
`Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.
120137
*/
138+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
121139
bool trylock_until(uint64_t millisec);
122140

141+
/** Try to lock the mutex until specified time
142+
@param abs_time absolute timeout time, referenced to Kernel::get_ms_count()
143+
@return true if the mutex was acquired, false otherwise.
144+
@note the underlying RTOS may have a limit to the maximum wait time
145+
due to internal 32-bit computations, but this is guaranteed to work if the
146+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
147+
the lock attempt will time out earlier than specified.
148+
149+
@note You cannot call this function from ISR context.
150+
*/
151+
bool trylock_until(Kernel::Clock::time_point abs_time);
152+
123153
/**
124154
Unlock the mutex that has previously been locked by the same thread
125155
@@ -178,11 +208,21 @@ inline bool Mutex::trylock_for(uint32_t)
178208
return true;
179209
}
180210

211+
inline bool Mutex::trylock_for(Kernel::Clock::duration_u32)
212+
{
213+
return true;
214+
}
215+
181216
inline bool Mutex::trylock_until(uint64_t)
182217
{
183218
return true;
184219
}
185220

221+
inline bool Mutex::trylock_until(Kernel::Clock::time_point)
222+
{
223+
return true;
224+
}
225+
186226
inline void Mutex::unlock()
187227
{
188228
}

rtos/source/Mutex.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929

3030
#if MBED_CONF_RTOS_PRESENT
3131

32+
using namespace std::chrono_literals;
33+
using std::milli;
34+
using std::chrono::duration;
35+
3236
namespace rtos {
3337

3438
Mutex::Mutex()
@@ -71,20 +75,25 @@ void Mutex::lock(void)
7175

7276
bool Mutex::trylock()
7377
{
74-
return trylock_for(0);
78+
return trylock_for(0s);
7579
}
7680

7781
bool Mutex::trylock_for(uint32_t millisec)
7882
{
79-
osStatus status = osMutexAcquire(_id, millisec);
83+
return trylock_for(duration<uint32_t, milli>(millisec));
84+
}
85+
86+
bool Mutex::trylock_for(Kernel::Clock::duration_u32 rel_time)
87+
{
88+
osStatus status = osMutexAcquire(_id, rel_time.count());
8089
if (status == osOK) {
8190
_count++;
8291
return true;
8392
}
8493

8594
bool success = (status == osOK ||
86-
(status == osErrorResource && millisec == 0) ||
87-
(status == osErrorTimeout && millisec != osWaitForever));
95+
(status == osErrorResource && rel_time == rel_time.zero()) ||
96+
(status == osErrorTimeout && rel_time <= Kernel::wait_for_u32_max));
8897

8998
if (!success && !mbed_get_error_in_progress()) {
9099
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "Mutex lock failed", status);
@@ -95,15 +104,20 @@ bool Mutex::trylock_for(uint32_t millisec)
95104

96105
bool Mutex::trylock_until(uint64_t millisec)
97106
{
98-
uint64_t now = Kernel::get_ms_count();
107+
return trylock_until(Kernel::Clock::time_point(duration<uint64_t, milli>(millisec)));
108+
}
109+
110+
bool Mutex::trylock_until(Kernel::Clock::time_point abs_time)
111+
{
112+
Kernel::Clock::time_point now = Kernel::Clock::now();
99113

100-
if (now >= millisec) {
114+
if (now >= abs_time) {
101115
return trylock();
102-
} else if (millisec - now >= osWaitForever) {
116+
} else if (abs_time - now > Kernel::wait_for_u32_max) {
103117
// API permits early return
104-
return trylock_for(osWaitForever - 1);
118+
return trylock_for(Kernel::wait_for_u32_max);
105119
} else {
106-
return trylock_for(millisec - now);
120+
return trylock_for(abs_time - now);
107121
}
108122
}
109123

0 commit comments

Comments
 (0)