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