diff --git a/rtos/Mutex.h b/rtos/Mutex.h index afd2fb2047..49963302c0 100644 --- a/rtos/Mutex.h +++ b/rtos/Mutex.h @@ -27,6 +27,7 @@ #include "rtos/mbed_rtos_types.h" #include "rtos/mbed_rtos1_types.h" #include "rtos/mbed_rtos_storage.h" +#include "rtos/Kernel.h" #include "platform/NonCopyable.h" #include "platform/ScopedLock.h" @@ -105,9 +106,23 @@ public: the lock attempt will time out earlier than specified. @note You cannot call this function from ISR context. + @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. */ + MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.") bool trylock_for(uint32_t millisec); + /** Try to lock the mutex for a specified time + @param rel_time timeout value. + @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(Kernel::Clock::duration_u32 rel_time); + /** 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. @@ -117,9 +132,24 @@ public: the lock attempt will time out earlier than specified. @note You cannot call this function from ISR context. + @deprecated Pass a chrono time_point, not an integer millisecond count. For example use + `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`. */ + 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`.") bool trylock_until(uint64_t millisec); + /** Try to lock the mutex until specified time + @param abs_time 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(Kernel::Clock::time_point abs_time); + /** Unlock the mutex that has previously been locked by the same thread @@ -178,11 +208,21 @@ inline bool Mutex::trylock_for(uint32_t) return true; } +inline bool Mutex::trylock_for(Kernel::Clock::duration_u32) +{ + return true; +} + inline bool Mutex::trylock_until(uint64_t) { return true; } +inline bool Mutex::trylock_until(Kernel::Clock::time_point) +{ + return true; +} + inline void Mutex::unlock() { } diff --git a/rtos/source/Mutex.cpp b/rtos/source/Mutex.cpp index 5742822abc..6860a7884d 100644 --- a/rtos/source/Mutex.cpp +++ b/rtos/source/Mutex.cpp @@ -29,6 +29,10 @@ #if MBED_CONF_RTOS_PRESENT +using namespace std::chrono_literals; +using std::milli; +using std::chrono::duration; + namespace rtos { Mutex::Mutex() @@ -71,20 +75,25 @@ void Mutex::lock(void) bool Mutex::trylock() { - return trylock_for(0); + return trylock_for(0s); } bool Mutex::trylock_for(uint32_t millisec) { - osStatus status = osMutexAcquire(_id, millisec); + return trylock_for(duration(millisec)); +} + +bool Mutex::trylock_for(Kernel::Clock::duration_u32 rel_time) +{ + osStatus status = osMutexAcquire(_id, rel_time.count()); if (status == osOK) { _count++; return true; } bool success = (status == osOK || - (status == osErrorResource && millisec == 0) || - (status == osErrorTimeout && millisec != osWaitForever)); + (status == osErrorResource && rel_time == rel_time.zero()) || + (status == osErrorTimeout && rel_time <= Kernel::wait_for_u32_max)); if (!success && !mbed_get_error_in_progress()) { 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) bool Mutex::trylock_until(uint64_t millisec) { - uint64_t now = Kernel::get_ms_count(); + return trylock_until(Kernel::Clock::time_point(duration(millisec))); +} - if (now >= millisec) { +bool Mutex::trylock_until(Kernel::Clock::time_point abs_time) +{ + Kernel::Clock::time_point now = Kernel::Clock::now(); + + if (now >= abs_time) { return trylock(); - } else if (millisec - now >= osWaitForever) { + } else if (abs_time - now > Kernel::wait_for_u32_max) { // API permits early return - return trylock_for(osWaitForever - 1); + return trylock_for(Kernel::wait_for_u32_max); } else { - return trylock_for(millisec - now); + return trylock_for(abs_time - now); } }