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
Kevin Bracey 2017-11-10 15:01:51 +02:00
parent bbefeb4432
commit cd573a603f
2 changed files with 50 additions and 5 deletions

View File

@ -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);
}
}

View File

@ -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();