Skip to content

Commit 53cfe0f

Browse files
committed
Add Chrono support to Semaphore
1 parent 0223d92 commit 53cfe0f

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

rtos/Semaphore.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
#define SEMAPHORE_H
2525

2626
#include <stdint.h>
27+
#include <chrono>
2728
#include "rtos/mbed_rtos_types.h"
2829
#include "rtos/mbed_rtos1_types.h"
2930
#include "rtos/mbed_rtos_storage.h"
31+
#include "rtos/Kernel.h"
3032
#include "platform/mbed_toolchain.h"
3133
#include "platform/NonCopyable.h"
3234

@@ -81,9 +83,19 @@ class Semaphore : private mbed::NonCopyable<Semaphore> {
8183
@return true if a resource was acquired, false otherwise.
8284
8385
@note You may call this function from ISR context if the millisec parameter is set to 0.
86+
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
8487
*/
88+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
8589
bool try_acquire_for(uint32_t millisec);
8690

91+
/** Wait until a Semaphore resource becomes available.
92+
@param rel_time timeout value.
93+
@return true if a resource was acquired, false otherwise.
94+
95+
@note You may call this function from ISR context if the rel_time parameter is set to 0.
96+
*/
97+
bool try_acquire_for(Kernel::Clock::duration_u32 rel_time);
98+
8799
/** Wait until a Semaphore resource becomes available.
88100
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
89101
@return true if a resource was acquired, false otherwise.
@@ -93,9 +105,24 @@ class Semaphore : private mbed::NonCopyable<Semaphore> {
93105
the acquire attempt will time out earlier than specified.
94106
95107
@note You cannot call this function from ISR context.
108+
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use
109+
`Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.
96110
*/
111+
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`.")
97112
bool try_acquire_until(uint64_t millisec);
98113

114+
/** Wait until a Semaphore resource becomes available.
115+
@param millisec absolute timeout time, referenced to Kernel::get_ms_count()
116+
@return true if a resource was acquired, false otherwise.
117+
@note the underlying RTOS may have a limit to the maximum wait time
118+
due to internal 32-bit computations, but this is guaranteed to work if the
119+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
120+
the acquire attempt will time out earlier than specified.
121+
122+
@note You cannot call this function from ISR context.
123+
*/
124+
bool try_acquire_until(Kernel::Clock::time_point abs_time);
125+
99126
/** Release a Semaphore resource that was obtain with Semaphore::acquire.
100127
@return status code that indicates the execution status of the function:
101128
@a osOK the token has been correctly released.

rtos/source/Semaphore.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929

3030
#include <string.h>
3131

32+
using namespace std::chrono_literals;
33+
using std::chrono::duration;
34+
using std::milli;
35+
3236
namespace rtos {
3337

3438
Semaphore::Semaphore(int32_t count)
@@ -104,43 +108,53 @@ void Semaphore::acquire()
104108
}
105109

106110
bool Semaphore::try_acquire_for(uint32_t millisec)
111+
{
112+
return try_acquire_for(duration<uint32_t, milli>(millisec));
113+
}
114+
115+
bool Semaphore::try_acquire_for(Kernel::Clock::duration_u32 rel_time)
107116
{
108117
#if MBED_CONF_RTOS_PRESENT
109-
osStatus_t status = osSemaphoreAcquire(_id, millisec);
118+
osStatus_t status = osSemaphoreAcquire(_id, rel_time.count());
110119
if (status == osOK) {
111120
return true;
112121
}
113122

114-
bool success = (status == osErrorResource && millisec == 0) ||
115-
(status == osErrorTimeout && millisec != osWaitForever);
123+
bool success = (status == osErrorResource && rel_time == rel_time.zero()) ||
124+
(status == osErrorTimeout);
116125

117126
if (!success) {
118127
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_SEMAPHORE_LOCK_FAILED), "Semaphore acquire failed", status);
119128
}
120129
return false;
121130
#else
122131
sem_wait_capture capture = { this, false };
123-
mbed::internal::do_timed_sleep_relative_or_forever(millisec, semaphore_available, &capture);
132+
mbed::internal::do_timed_sleep_relative_or_forever(rel_time, semaphore_available, &capture);
124133
return capture.acquired;
125134
#endif
126135
}
127136

128137
bool Semaphore::try_acquire_until(uint64_t millisec)
138+
{
139+
return try_acquire_until(Kernel::Clock::time_point(duration<uint64_t, milli>(millisec)));
140+
}
141+
142+
bool Semaphore::try_acquire_until(Kernel::Clock::time_point abs_time)
129143
{
130144
#if MBED_CONF_RTOS_PRESENT
131-
uint64_t now = Kernel::get_ms_count();
145+
Kernel::Clock::time_point now = Kernel::Clock::now();
132146

133-
if (now >= millisec) {
147+
if (now >= abs_time) {
134148
return try_acquire();
135-
} else if (millisec - now >= osWaitForever) {
149+
} else if (abs_time - now > Kernel::wait_for_u32_max) {
136150
// API permits early return
137-
return try_acquire_for(osWaitForever - 1);
151+
return try_acquire_for(Kernel::wait_for_u32_max);
138152
} else {
139-
return try_acquire_for(millisec - now);
153+
return try_acquire_for(abs_time - now);
140154
}
141155
#else
142156
sem_wait_capture capture = { this, false };
143-
mbed::internal::do_timed_sleep_absolute(millisec, semaphore_available, &capture);
157+
mbed::internal::do_timed_sleep_absolute(abs_time, semaphore_available, &capture);
144158
return capture.acquired;
145159
#endif
146160
}

0 commit comments

Comments
 (0)