mirror of https://github.com/ARMmbed/mbed-os.git
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.pull/5419/head
parent
bbefeb4432
commit
cd573a603f
|
@ -20,6 +20,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
#include "rtos/Mutex.h"
|
||||
#include "rtos/Kernel.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "mbed_error.h"
|
||||
|
@ -58,11 +59,30 @@ osStatus Mutex::lock(uint32_t millisec) {
|
|||
}
|
||||
|
||||
bool Mutex::trylock() {
|
||||
if (osMutexAcquire(_id, 0) == osOK) {
|
||||
_count++;
|
||||
return trylock_for(0);
|
||||
}
|
||||
|
||||
bool Mutex::trylock_for(uint32_t millisec) {
|
||||
osStatus status = lock(millisec);
|
||||
if (status == osOK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MBED_ASSERT(status == osErrorTimeout || status == osErrorResource);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mutex::trylock_until(uint64_t millisec) {
|
||||
uint64_t now = Kernel::get_ms_count();
|
||||
|
||||
if (now >= millisec) {
|
||||
return trylock();
|
||||
} else if (millisec - now >= osWaitForever) {
|
||||
// API permits early return
|
||||
return trylock_for(osWaitForever - 1);
|
||||
} else {
|
||||
return false;
|
||||
return trylock_for(millisec - now);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
29
rtos/Mutex.h
29
rtos/Mutex.h
|
@ -78,11 +78,36 @@ public:
|
|||
|
||||
/** Try to lock the mutex, and return immediately
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note equivalent to trylock_for(0)
|
||||
|
||||
@note This function cannot be called from ISR context.
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool trylock();
|
||||
|
||||
/** Try to lock the mutex for a specified time
|
||||
@param millisec timeout value or 0 in case of no time-out.
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the lock attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool trylock_for(uint32_t millisec);
|
||||
|
||||
/** Try to lock the mutex until specified time
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@return true if the mutex was acquired, false otherwise.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
due to internal 32-bit computations, but this is guaranteed to work if the
|
||||
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
|
||||
the lock attempt will time out earlier than specified.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool trylock_until(uint64_t millisec);
|
||||
|
||||
/** Unlock the mutex that has previously been locked by the same thread
|
||||
@return status code that indicates the execution status of the function:
|
||||
@a osOK the mutex has been released.
|
||||
|
@ -90,7 +115,7 @@ public:
|
|||
@a osErrorResource the mutex was not locked or the current thread wasn't the owner.
|
||||
@a osErrorISR this function cannot be called from the interrupt service routine.
|
||||
|
||||
@note This function cannot be called from ISR context.
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
osStatus unlock();
|
||||
|
||||
|
|
Loading…
Reference in New Issue