mirror of https://github.com/ARMmbed/mbed-os.git
Add Chrono support to Semaphore
parent
0223d92f7e
commit
53cfe0f610
|
@ -24,9 +24,11 @@
|
|||
#define SEMAPHORE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <chrono>
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
|
@ -81,9 +83,34 @@ public:
|
|||
@return true if a resource was acquired, false otherwise.
|
||||
|
||||
@note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
@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 try_acquire_for(uint32_t millisec);
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
@param rel_time timeout value.
|
||||
@return true if a resource was acquired, false otherwise.
|
||||
|
||||
@note You may call this function from ISR context if the rel_time parameter is set to 0.
|
||||
*/
|
||||
bool try_acquire_for(Kernel::Clock::duration_u32 rel_time);
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@return true if a resource 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 acquire 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 try_acquire_until(uint64_t millisec);
|
||||
|
||||
/** Wait until a Semaphore resource becomes available.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
|
||||
@return true if a resource was acquired, false otherwise.
|
||||
|
@ -94,7 +121,7 @@ public:
|
|||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
bool try_acquire_until(uint64_t millisec);
|
||||
bool try_acquire_until(Kernel::Clock::time_point abs_time);
|
||||
|
||||
/** Release a Semaphore resource that was obtain with Semaphore::acquire.
|
||||
@return status code that indicates the execution status of the function:
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using std::chrono::duration;
|
||||
using std::milli;
|
||||
|
||||
namespace rtos {
|
||||
|
||||
Semaphore::Semaphore(int32_t count)
|
||||
|
@ -104,15 +108,20 @@ void Semaphore::acquire()
|
|||
}
|
||||
|
||||
bool Semaphore::try_acquire_for(uint32_t millisec)
|
||||
{
|
||||
return try_acquire_for(duration<uint32_t, milli>(millisec));
|
||||
}
|
||||
|
||||
bool Semaphore::try_acquire_for(Kernel::Clock::duration_u32 rel_time)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osStatus_t status = osSemaphoreAcquire(_id, millisec);
|
||||
osStatus_t status = osSemaphoreAcquire(_id, rel_time.count());
|
||||
if (status == osOK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = (status == osErrorResource && millisec == 0) ||
|
||||
(status == osErrorTimeout && millisec != osWaitForever);
|
||||
bool success = (status == osErrorResource && rel_time == rel_time.zero()) ||
|
||||
(status == osErrorTimeout);
|
||||
|
||||
if (!success) {
|
||||
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_SEMAPHORE_LOCK_FAILED), "Semaphore acquire failed", status);
|
||||
|
@ -120,27 +129,32 @@ bool Semaphore::try_acquire_for(uint32_t millisec)
|
|||
return false;
|
||||
#else
|
||||
sem_wait_capture capture = { this, false };
|
||||
mbed::internal::do_timed_sleep_relative_or_forever(millisec, semaphore_available, &capture);
|
||||
mbed::internal::do_timed_sleep_relative_or_forever(rel_time, semaphore_available, &capture);
|
||||
return capture.acquired;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Semaphore::try_acquire_until(uint64_t millisec)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
uint64_t now = Kernel::get_ms_count();
|
||||
return try_acquire_until(Kernel::Clock::time_point(duration<uint64_t, milli>(millisec)));
|
||||
}
|
||||
|
||||
if (now >= millisec) {
|
||||
bool Semaphore::try_acquire_until(Kernel::Clock::time_point abs_time)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
Kernel::Clock::time_point now = Kernel::Clock::now();
|
||||
|
||||
if (now >= abs_time) {
|
||||
return try_acquire();
|
||||
} else if (millisec - now >= osWaitForever) {
|
||||
} else if (abs_time - now > Kernel::wait_for_u32_max) {
|
||||
// API permits early return
|
||||
return try_acquire_for(osWaitForever - 1);
|
||||
return try_acquire_for(Kernel::wait_for_u32_max);
|
||||
} else {
|
||||
return try_acquire_for(millisec - now);
|
||||
return try_acquire_for(abs_time - now);
|
||||
}
|
||||
#else
|
||||
sem_wait_capture capture = { this, false };
|
||||
mbed::internal::do_timed_sleep_absolute(millisec, semaphore_available, &capture);
|
||||
mbed::internal::do_timed_sleep_absolute(abs_time, semaphore_available, &capture);
|
||||
return capture.acquired;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue