mirror of https://github.com/ARMmbed/mbed-os.git
Add ConditionVariable::wait_until
Given the 64-bit timebase, add wait_until to ConditionVariable. Move the timeout example to wait_until(), and give wait_for() an alternative example, as it's no longer the best option for a timeout. Tidy up - remove the redundant RESUME_SIGNAL definition.pull/6056/head
parent
866b669d6e
commit
029751db20
|
@ -20,6 +20,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "rtos/ConditionVariable.h"
|
#include "rtos/ConditionVariable.h"
|
||||||
|
#include "rtos/Kernel.h"
|
||||||
#include "rtos/Thread.h"
|
#include "rtos/Thread.h"
|
||||||
|
|
||||||
#include "mbed_error.h"
|
#include "mbed_error.h"
|
||||||
|
@ -27,7 +28,6 @@
|
||||||
|
|
||||||
namespace rtos {
|
namespace rtos {
|
||||||
|
|
||||||
|
|
||||||
ConditionVariable::Waiter::Waiter(): sem(0), prev(NULL), next(NULL), in_list(false)
|
ConditionVariable::Waiter::Waiter(): sem(0), prev(NULL), next(NULL), in_list(false)
|
||||||
{
|
{
|
||||||
// No initialization to do
|
// No initialization to do
|
||||||
|
@ -64,6 +64,24 @@ bool ConditionVariable::wait_for(uint32_t millisec)
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConditionVariable::wait_until(uint64_t millisec)
|
||||||
|
{
|
||||||
|
uint64_t now = Kernel::get_ms_count();
|
||||||
|
|
||||||
|
if (now >= millisec) {
|
||||||
|
// Time has already passed - standard behaviour is to
|
||||||
|
// treat as a "try".
|
||||||
|
return wait_for(0);
|
||||||
|
} else if (millisec - now >= osWaitForever) {
|
||||||
|
// Exceeds maximum delay of underlying wait_for -
|
||||||
|
// spuriously wake after 49 days, indicating no timeout.
|
||||||
|
wait_for(osWaitForever - 1);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return wait_for(millisec - now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConditionVariable::notify_one()
|
void ConditionVariable::notify_one()
|
||||||
{
|
{
|
||||||
MBED_ASSERT(_mutex.get_owner() == Thread::gettid());
|
MBED_ASSERT(_mutex.get_owner() == Thread::gettid());
|
||||||
|
|
|
@ -150,6 +150,39 @@ public:
|
||||||
*/
|
*/
|
||||||
void wait();
|
void wait();
|
||||||
|
|
||||||
|
/** Wait for a notification until specified time
|
||||||
|
*
|
||||||
|
* @param millisec absolute end time referenced to Kernel::get_ms_count()
|
||||||
|
* @return true if a timeout occurred, false otherwise.
|
||||||
|
*
|
||||||
|
* @note - The thread calling this function must be the owner of the
|
||||||
|
* ConditionVariable's mutex and it must be locked exactly once
|
||||||
|
* @note - Spurious notifications can occur so the caller of this API
|
||||||
|
* should check to make sure the condition they are waiting on has
|
||||||
|
* been met
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* mutex.lock();
|
||||||
|
* uint64_t end_time = Kernel::get_ms_count() + COND_WAIT_TIMEOUT;
|
||||||
|
*
|
||||||
|
* while (!condition_met) {
|
||||||
|
* if (cond.wait_until(end_time)) {
|
||||||
|
* break;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* if (condition_met) {
|
||||||
|
* function_to_handle_condition();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* mutex.unlock();
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @note You cannot call this function from ISR context.
|
||||||
|
*/
|
||||||
|
bool wait_until(uint64_t millisec);
|
||||||
|
|
||||||
/** Wait for a notification or timeout
|
/** Wait for a notification or timeout
|
||||||
*
|
*
|
||||||
* @param millisec timeout value or osWaitForever in case of no time-out.
|
* @param millisec timeout value or osWaitForever in case of no time-out.
|
||||||
|
@ -164,15 +197,12 @@ public:
|
||||||
* Example:
|
* Example:
|
||||||
* @code
|
* @code
|
||||||
* mutex.lock();
|
* mutex.lock();
|
||||||
* Timer timer;
|
|
||||||
* timer.start();
|
|
||||||
*
|
*
|
||||||
* bool timed_out = false;
|
* while (!condition_met) {
|
||||||
* uint32_t time_left = TIMEOUT;
|
* cond.wait_for(MAX_SLEEP_TIME);
|
||||||
* while (!condition_met && !timed_out) {
|
* if (!condition_met) {
|
||||||
* timed_out = cond.wait_for(time_left);
|
* do_other_work_while_condition_false();
|
||||||
* uint32_t elapsed = timer.read_ms();
|
* }
|
||||||
* time_left = elapsed > TIMEOUT ? 0 : TIMEOUT - elapsed;
|
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* if (condition_met) {
|
* if (condition_met) {
|
||||||
|
|
Loading…
Reference in New Issue