Mbed OS Reference
Loading...
Searching...
No Matches
ConditionVariable Class Reference

The ConditionVariable class is a synchronization primitive that allows threads to wait until a particular condition occurs. More...

#include <ConditionVariable.h>

Inheritance diagram for ConditionVariable:
NonCopyable< ConditionVariable >

Public Member Functions

 ConditionVariable (Mutex &mutex)
 Create and initialize a ConditionVariable object. More...
 
void wait ()
 Wait for a notification. More...
 
template<typename Predicate >
void wait (Predicate pred)
 Wait for a predicate. More...
 
bool wait_until (uint64_t millisec)
 Wait for a notification until the specified time. More...
 
cv_status wait_until (Kernel::Clock::time_point abs_time)
 Wait for a notification until the specified time. More...
 
template<class Predicate >
bool wait_until (Kernel::Clock::time_point abs_time, Predicate pred)
 Wait for a predicate until the specified time. More...
 
bool wait_for (uint32_t millisec)
 Wait for a notification or timeout. More...
 
cv_status wait_for (Kernel::Clock::duration_u32 rel_time)
 Wait for a notification or timeout. More...
 
template<class Predicate >
bool wait_for (Kernel::Clock::duration rel_time, Predicate pred)
 Wait for a predicate or timeout. More...
 
void notify_one ()
 Notify one waiter on this condition variable that a condition changed. More...
 
void notify_all ()
 Notify all waiters on this condition variable that a condition changed. More...
 
 ~ConditionVariable ()
 ConditionVariable destructor. More...
 

Detailed Description

The ConditionVariable class is a synchronization primitive that allows threads to wait until a particular condition occurs.

Use the condition variable in conjunction with a mutex to safely wait for or notify waiters of condition changes to a resource accessible by multiple threads.

The thread that intends to wait on a ConditionVariable must:

  • Acquire a lock on a mutex.
  • Execute wait, wait_for or wait_until. While the thread is waiting, the mutex is unlocked.
  • When the condition variable has been notified, or in the case of wait_for and wait_until the timeout expires, the thread is awakened.

The thread that intends to notify a ConditionVariable must:

  • Acquire a lock on the mutex used to construct the condition variable.
  • Execute notify_one or notify_all on the condition variable.

All threads waiting on the condition variable wake when ConditionVariable::notify_all is called. At least one thread waiting on the condition variable wakes when ConditionVariable::notify_one is called.

While a thread is waiting for notification of a ConditionVariable, it releases the lock held on the mutex. The ConditionVariable reacquires the mutex lock before exiting the wait function.

Unspecified behavior

Undefined behavior

Note
Synchronization level: Thread safe
Bare metal profile: This class is not supported.

Example:

#include "mbed.h"
Mutex mutex;
// These variables are protected by locking the mutex.
uint32_t work_count = 0;
bool done = false;
void worker_thread()
{
// Acquire lock on mutex before accessing protected variables and waiting.
mutex.lock();
while (done == false) {
printf("Worker thread: Count: %lu\r\n", work_count);
// Wait for main thread to notify the condition variable.
printf("Worker thread: Waiting\r\n");
cv.wait();
}
printf("Worker: Exiting\r\n");
// The condition variable acquires the lock when exiting the `wait` function.
// Unlock mutex when exiting the thread.
mutex.unlock();
}
int main()
{
Thread thread;
thread.start(worker_thread);
for (int i = 0; i < 5; i++) {
// Acquire lock on mutex before modifying variables and notifying.
mutex.lock();
// Change count and notify waiters.
work_count++;
printf("Main thread: Set count to: %lu\r\n", work_count);
printf("Main thread: Notifying worker thread\r\n");
cv.notify_all();
// Mutex must be unlocked before the worker thread can acquire it.
mutex.unlock();
}
// Change done and notify waiters of this.
mutex.lock();
done = true;
cv.notify_all();
mutex.unlock();
thread.join();
printf("Main: Exiting\r\n");
}
The ConditionVariable class is a synchronization primitive that allows threads to wait until a partic...
The Mutex class is used to synchronize the execution of threads.
Definition: Mutex.h:70
void unlock()
Unlock the mutex that has previously been locked by the same thread.
void lock()
Wait until a Mutex becomes available.
void sleep_for(uint32_t millisec)
Sleep for a specified time period in millisec:

Definition at line 168 of file ConditionVariable.h.

Constructor & Destructor Documentation

◆ ConditionVariable()

ConditionVariable ( Mutex mutex)

Create and initialize a ConditionVariable object.

Note
You cannot call this function from ISR context.

◆ ~ConditionVariable()

ConditionVariable destructor.

Note
You cannot call this function from ISR context.

Member Function Documentation

◆ wait() [1/2]

void wait ( )

Wait for a notification.

Wait causes the current thread to block until the condition variable receives a notification from another thread.

Note
- The thread calling this function must be the owner of the ConditionVariable's mutex, and it must be locked exactly once.
- Spurious notifications can occur, so the caller of this API should check to make sure the condition the caller is waiting on has been met.
- The current thread releases the mutex while inside the wait function and reacquires it upon exiting the function.

Example:

mutex.lock();
while (!condition_met) {
cond.wait();
}
function_to_handle_condition();
mutex.unlock();
Note
You cannot call this function from ISR context.

◆ wait() [2/2]

void wait ( Predicate  pred)

Wait for a predicate.

Wait causes the current thread to block until the predicate is true.

Parameters
predA function-like object such that pred() is convertible to bool
Note
- The thread calling this function must be the owner of the ConditionVariable's mutex, and it must be locked exactly once.
- The current thread releases the mutex while inside the wait function and reacquires it upon exiting the function.

Example:

extern bool data_available();
mutex.lock();
cond.wait(data_available);
function_to_handle_data();
mutex.unlock();
Note
You cannot call this function from ISR context.

Definition at line 237 of file ConditionVariable.h.

◆ wait_until() [1/3]

bool wait_until ( uint64_t  millisec)

Wait for a notification until the specified time.

Wait until causes the current thread to block until the condition variable is notified, or a specific time given by millisec parameter is reached.

Parameters
millisecAbsolute end time referenced to Kernel::get_ms_count()
Returns
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.
- Spurious notifications can occur, so the caller of this API should check to make sure the condition the caller is waiting on has been met.
- The current thread releases the lock while inside the wait function and reacquires it upon exiting the function.

Example:

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();
uint64_t get_ms_count()
Read the current RTOS kernel millisecond tick count.
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.

◆ wait_until() [2/3]

cv_status wait_until ( Kernel::Clock::time_point  abs_time)

Wait for a notification until the specified time.

Wait until causes the current thread to block until the condition variable is notified, or a specific time given by millisec parameter is reached.

Parameters
abs_timeAbsolute end time referenced to Kernel::Clock
Returns
cv_status::timeout if a timeout occurred, cv_status::no_timeout otherwise.
Note
- The thread calling this function must be the owner of the ConditionVariable's mutex, and it must be locked exactly once.
- Spurious notifications can occur, so the caller of this API should check to make sure the condition the caller is waiting on has been met.
- The current thread releases the lock while inside the wait function and reacquires it upon exiting the function.

Example:

mutex.lock();
Kernel::Clock::time_point end_time = Kernel::Clock::now() + 2s;
while (!condition_met) {
if (cond.wait_until(end_time) == cv_status::timeout) {
break;
}
}
if (condition_met) {
function_to_handle_condition();
}
mutex.unlock();
Note
You cannot call this function from ISR context.

◆ wait_until() [3/3]

bool wait_until ( Kernel::Clock::time_point  abs_time,
Predicate  pred 
)

Wait for a predicate until the specified time.

Wait until causes the current thread to block until the predicate is true, or a specific time given by abs_time parameter is reached.

Parameters
abs_timeAbsolute end time referenced to Kernel::Clock
predA function-like object such that pred() is convertible to bool
Returns
The state of the predicate
Note
- The thread calling this function must be the owner of the ConditionVariable's mutex, and it must be locked exactly once.
- The current thread releases the mutex while inside the wait function and reacquires it upon exiting the function.

Example:

extern bool data_available();
mutex.lock();
if (cond.wait_until(Kernel::Clock::now() + 2s, data_available)) {
function_to_handle_data();
}
mutex.unlock();
Note
You cannot call this function from ISR context.

Definition at line 361 of file ConditionVariable.h.

◆ wait_for() [1/3]

bool wait_for ( uint32_t  millisec)

Wait for a notification or timeout.

Wait for causes the current thread to block until the condition variable receives a notification from another thread, or the timeout specified by the millisec parameter is reached.

Parameters
millisecTimeout value or osWaitForever in case of no timeout.
Returns
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.
- Spurious notifications can occur, so the caller of this API should check to make sure the condition the caller is waiting on has been met.
- The current thread releases the lock while inside the wait function and reacquire it upon exiting the function.

Example:

mutex.lock();
while (!condition_met) {
cond.wait_for(MAX_SLEEP_TIME);
if (!condition_met) {
do_other_work_while_condition_false();
}
}
if (condition_met) {
function_to_handle_condition();
}
mutex.unlock();
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.

◆ wait_for() [2/3]

cv_status wait_for ( Kernel::Clock::duration_u32  rel_time)

Wait for a notification or timeout.

Wait for causes the current thread to block until the condition variable receives a notification from another thread, or the timeout specified by the millisec parameter is reached.

Parameters
rel_timeTimeout value.
Returns
cv_status::timeout if a timeout occurred, cv_status::no_timeout otherwise.
Note
- The thread calling this function must be the owner of the ConditionVariable's mutex, and it must be locked exactly once.
- Spurious notifications can occur, so the caller of this API should check to make sure the condition the caller is waiting on has been met.
- The current thread releases the lock while inside the wait function and reacquire it upon exiting the function.

Example:

mutex.lock();
while (!condition_met) {
cond.wait_for(MAX_SLEEP_TIME);
if (!condition_met) {
do_other_work_while_condition_false();
}
}
if (condition_met) {
function_to_handle_condition();
}
mutex.unlock();
Note
You cannot call this function from ISR context.

◆ wait_for() [3/3]

bool wait_for ( Kernel::Clock::duration  rel_time,
Predicate  pred 
)

Wait for a predicate or timeout.

Wait for causes the current thread to block until the predicate is true, or the timeout specified by the rel_time parameter is reached.

Parameters
rel_timeTimeout value.
preda function-like object such that pred() is convertible to bool
Returns
The state of the predicate
Note
- The thread calling this function must be the owner of the ConditionVariable's mutex, and it must be locked exactly once.
- The current thread releases the mutex while inside the wait function and reacquire it upon exiting the function.

Example:

extern bool data_available();
mutex.lock();
if (cond.wait_for(2s, data_available)) {
function_to_handle_data();
}
mutex.unlock();
Note
You cannot call this function from ISR context.

Definition at line 486 of file ConditionVariable.h.

◆ notify_one()

void notify_one ( )

Notify one waiter on this condition variable that a condition changed.

This function unblocks one of the threads waiting for the condition variable.

Note
- The thread calling this function must be the owner of the ConditionVariable's mutex.
- The thread that is unblocked on ConditionVariable::notify_one is undefined if there are multiple waiters.
You cannot call this function from ISR context.

◆ notify_all()

void notify_all ( )

Notify all waiters on this condition variable that a condition changed.

This function unblocks all of the threads waiting for the condition variable.

Note
- The thread calling this function must be the owner of the ConditionVariable's mutex.
- If there are one or more waiters and one or more threads attempting to acquire the condition variable's mutex the order in which the mutex is acquired is undefined.
You cannot call this function from ISR context.