mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Add Chrono support to Mutex
							parent
							
								
									53cfe0f610
								
							
						
					
					
						commit
						2c4e59012f
					
				
							
								
								
									
										40
									
								
								rtos/Mutex.h
								
								
								
								
							
							
						
						
									
										40
									
								
								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()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<uint32_t, milli>(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<uint64_t, milli>(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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue