Skip to content

Commit cd573a6

Browse files
committed
Add Mutex::trylock_until and trylock_for
Given the 64-bit timebase, add trylock_until to Mutex. Naming is based on a combination of Mutex::trylock, Thread::wait_until, and C++11 timed_mutex::try_lock_until. pthreads and C11 use "timedlock", but that's not a good fit against our existing trylock() and lock(timeout) - they have only absolute-time waits, not relative. To increase the similarity to C++11, add trylock_for - same parameters as lock, but with the bool return value of trylock and trylock_until. Add an assertion when convering status codes to booleans to check that there are no non-timeout errors.
1 parent bbefeb4 commit cd573a6

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

rtos/Mutex.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* SOFTWARE.
2121
*/
2222
#include "rtos/Mutex.h"
23+
#include "rtos/Kernel.h"
2324

2425
#include <string.h>
2526
#include "mbed_error.h"
@@ -58,11 +59,30 @@ osStatus Mutex::lock(uint32_t millisec) {
5859
}
5960

6061
bool Mutex::trylock() {
61-
if (osMutexAcquire(_id, 0) == osOK) {
62-
_count++;
62+
return trylock_for(0);
63+
}
64+
65+
bool Mutex::trylock_for(uint32_t millisec) {
66+
osStatus status = lock(millisec);
67+
if (status == osOK) {
6368
return true;
69+
}
70+
71+
MBED_ASSERT(status == osErrorTimeout || status == osErrorResource);
72+
73+
return false;
74+
}
75+
76+
bool Mutex::trylock_until(uint64_t millisec) {
77+
uint64_t now = Kernel::get_ms_count();
78+
79+
if (now >= millisec) {
80+
return trylock();
81+
} else if (millisec - now >= osWaitForever) {
82+
// API permits early return
83+
return trylock_for(osWaitForever - 1);
6484
} else {
65-
return false;
85+
return trylock_for(millisec - now);
6686
}
6787
}
6888

rtos/Mutex.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,44 @@ class Mutex : private mbed::NonCopyable<Mutex> {
7878

7979
/** Try to lock the mutex, and return immediately
8080
@return true if the mutex was acquired, false otherwise.
81+
@note equivalent to trylock_for(0)
8182
82-
@note This function cannot be called from ISR context.
83+
@note You cannot call this function from ISR context.
8384
*/
8485
bool trylock();
8586

87+
/** Try to lock the mutex for a specified time
88+
@param millisec timeout value or 0 in case of no time-out.
89+
@return true if the mutex was acquired, false otherwise.
90+
@note the underlying RTOS may have a limit to the maximum wait time
91+
due to internal 32-bit computations, but this is guaranteed to work if the
92+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
93+
the lock attempt will time out earlier than specified.
94+
95+
@note You cannot call this function from ISR context.
96+
*/
97+
bool trylock_for(uint32_t millisec);
98+
99+
/** Try to lock the mutex until specified time
100+
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
101+
@return true if the mutex was acquired, false otherwise.
102+
@note the underlying RTOS may have a limit to the maximum wait time
103+
due to internal 32-bit computations, but this is guaranteed to work if the
104+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
105+
the lock attempt will time out earlier than specified.
106+
107+
@note You cannot call this function from ISR context.
108+
*/
109+
bool trylock_until(uint64_t millisec);
110+
86111
/** Unlock the mutex that has previously been locked by the same thread
87112
@return status code that indicates the execution status of the function:
88113
@a osOK the mutex has been released.
89114
@a osErrorParameter internal error.
90115
@a osErrorResource the mutex was not locked or the current thread wasn't the owner.
91116
@a osErrorISR this function cannot be called from the interrupt service routine.
92117
93-
@note This function cannot be called from ISR context.
118+
@note You cannot call this function from ISR context.
94119
*/
95120
osStatus unlock();
96121

0 commit comments

Comments
 (0)