diff --git a/rtos/Mutex.cpp b/rtos/Mutex.cpp index 44fefa0759..edc2cdcb52 100644 --- a/rtos/Mutex.cpp +++ b/rtos/Mutex.cpp @@ -20,6 +20,7 @@ * SOFTWARE. */ #include "rtos/Mutex.h" +#include "rtos/Kernel.h" #include #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); } } diff --git a/rtos/Mutex.h b/rtos/Mutex.h index 4273d14722..acd035e173 100644 --- a/rtos/Mutex.h +++ b/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();