µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os::rtos::condition_variable Class Reference

POSIX compliant condition variable. More...

#include <cmsis-plus/rtos/os.h>

+ Inheritance diagram for os::rtos::condition_variable:

Classes

class  attributes
 Condition variable attributes. More...
 

Public Member Functions

Constructors & Destructor
 condition_variable (const attributes &attr=initializer)
 Construct a condition variable object instance.
 
 condition_variable (const char *name, const attributes &attr=initializer)
 Construct a named condition variable object instance.
 
 ~condition_variable ()
 Destruct the condition variable object instance.
 
Operators
bool operator== (const condition_variable &rhs) const
 Compare condition variables.
 
Public Member Functions
result_t signal (void)
 Notify one thread waiting for a condition variable.
 
result_t broadcast (void)
 Notify all threads waiting for a condition variable.
 
result_t wait (mutex &mutex)
 Wait for a condition variable to be notified.
 
result_t timed_wait (mutex &mutex, clock::duration_t timeout)
 Timed wait for a condition variable to be notified.
 
Public Member Functions
const char * name (void) const
 Get object name.
 

Static Public Member Functions

Operators
static void * operator new (std::size_t bytes)
 Allocate space for a new object instance using the RTOS system allocator.
 
static void * operator new (std::size_t bytes, void *ptr)
 Emplace a new object instance.
 
static void * operator new[] (std::size_t bytes)
 Allocate space for an array of new object instances using the RTOS system allocator.
 
static void * operator new[] (std::size_t bytes, void *ptr)
 Emplace an array of new object instances.
 
static void operator delete (void *ptr, std::size_t bytes)
 Deallocate the dynamically allocated object instance. using the RTOS system allocator.
 
static void operator delete[] (void *ptr, std::size_t bytes)
 Deallocate the dynamically allocated array of object. instances using the RTOS system allocator.
 

Static Public Attributes

static const attributes initializer
 Default condition variable initialiser.
 

Detailed Description

POSIX compliant condition variable.

A condition variable is a synchronisation object which allows a thread to suspend execution, repeatedly, until some associated predicate becomes true. A thread whose execution is suspended on a condition variable is said to be blocked on the condition variable.

Scheduling Behaviour of Condition Variables

Synchronisation primitives that attempt to interfere with scheduling policy by specifying an ordering rule are considered undesirable. Threads waiting on mutexes and condition variables are selected to proceed in an order dependent upon the scheduling policy rather than in some fixed order (for example, FIFO or priority). Thus, the scheduling policy determines which thread(s) are awakened and allowed to proceed.

Cancellation and Condition Wait

A condition wait, whether timed or not, is a cancellation point. That is, the functions wait() or timed_wait() are points where a pending (or concurrent) cancellation request is noticed. The reason for this is that an indefinite wait is possible at these points-whatever event is being waited for, even if the program is totally correct, might never occur; for example, some input data being awaited might never be sent. By making condition wait a cancellation point, the thread can be cancelled and perform its cancellation cleanup handler even though it may be stuck in some indefinite wait.

A side-effect of acting on a cancellation request while a thread is blocked on a condition variable is to re-acquire the mutex before calling any of the cancellation cleanup handlers. This is done in order to ensure that the cancellation cleanup handler is executed in the same state as the critical code that lies both before and after the call to the condition wait function. This rule is also required when interfacing to POSIX threads from languages, such as Ada or C++, which may choose to map cancellation onto a language exception; this rule ensures that each exception handler guarding a critical section can always safely depend upon the fact that the associated mutex has already been locked regardless of exactly where within the critical section the exception was raised. Without this rule, there would not be a uniform rule that exception handlers could follow regarding the lock, and so coding would become very cumbersome.

Therefore, since some statement has to be made regarding the state of the lock when a cancellation is delivered during a wait, a definition has been chosen that makes application coding most convenient and error free.

When acting on a cancellation request while a thread is blocked on a condition variable, the implementation is required to ensure that the thread does not consume any condition signals directed at that condition variable if there are any other threads waiting on that condition variable. This rule is specified in order to avoid deadlock conditions that could occur if these two independent requests (one acting on a thread and the other acting on the condition variable) were not processed independently.

Performance of Mutexes and Condition Variables

Mutexes are expected to be locked only for a few instructions. This practice is almost automatically enforced by the desire of programmers to avoid long serial regions of execution (which would reduce total effective parallelism).

When using mutexes and condition variables, one tries to ensure that the usual case is to lock the mutex, access shared data, and unlock the mutex. Waiting on a condition variable should be a relatively rare situation. For example, when implementing a read-write lock, code that acquires a read-lock typically needs only to increment the count of readers (under mutual-exclusion) and return. The calling thread would actually wait on the condition variable only when there is already an active writer. So the efficiency of a synchronisation operation is bounded by the cost of mutex lock/unlock and not by condition wait. Note that in the usual case there is no context switch.

This is not to say that the efficiency of condition waiting is unimportant. Since there needs to be at least one context switch per Ada rendezvous, the efficiency of waiting on a condition variable is important. The cost of waiting on a condition variable should be little more than the minimal cost for a context switch plus the time to unlock and lock the mutex.

Example
mutex mx;
void
consumer(void)
{
// Do something
mx.lock();
// ...
while(!condition())
{
// ...
cv.wait();
// ...
}
// ...
mx.unlock(mx);
// Do something else.
}
void
producer(void)
{
// Do something
mx.lock();
// ...
if (some_condition())
{
// ...
cv.signal();
// ...
}
// ...
mx.unlock(mx);
// Do something else.
}
POSIX compliant condition variable.
Definition os-condvar.h:46
result_t signal(void)
Notify one thread waiting for a condition variable.
result_t wait(mutex &mutex)
Wait for a condition variable to be notified.
POSIX compliant mutex.
Definition os-mutex.h:53
result_t lock(void)
Lock/acquire the mutex.
Definition os-mutex.cpp:955
result_t unlock(void)
Unlock/release the mutex.
POSIX compatibility
Inspired by pthread_cond_t from <pthread.h> (IEEE Std 1003.1, 2013 Edition).

Definition at line 45 of file os-condvar.h.

Constructor & Destructor Documentation

◆ condition_variable() [1/2]

os::rtos::condition_variable::condition_variable ( const attributes attr = initializer)

Construct a condition variable object instance.

Parameters
[in]attrReference to attributes.
Errors
The constructor shall fail if:
  • EAGAIN - The system lacked the necessary resources (other than memory) to create the condition variable.
  • ENOMEM - Insufficient memory exists to initialise the condition variable.
The constructor shall not fail with an error code of EINTR.

This constructor shall initialise a condition variable object with attributes referenced by attr. If the attributes specified by attr are modified later, the condition variable attributes shall not be affected.

Upon successful initialisation, the state of the condition variable object shall become initialised.

Only the condition variable object itself may be used for performing synchronisation. It is not allowed to make copies of condition variable objects.

In cases where default condition variable attributes are appropriate, the variable condition_variable::initializer can be used to initialise condition variables. The effect shall be equivalent to creating a condition variables object with the default constructor.

If the attr attributes are modified after the condition_variable creation, the condition_variable attributes shall not be affected.

Warning
Cannot be invoked from Interrupt Service Routines.
POSIX compatibility
Inspired by pthread_cond_init() from <pthread.h> (IEEE Std 1003.1, 2013 Edition).

Definition at line 227 of file os-condvar.cpp.

◆ condition_variable() [2/2]

os::rtos::condition_variable::condition_variable ( const char *  name,
const attributes attr = initializer 
)

Construct a named condition variable object instance.

Parameters
[in]namePointer to name.
[in]attrReference to attributes.
Errors
The constructor shall fail if:
  • EAGAIN - The system lacked the necessary resources (other than memory) to create the condition variable.
  • ENOMEM - Insufficient memory exists to initialise the condition variable.
The constructor shall not fail with an error code of EINTR.

◆ ~condition_variable()

os::rtos::condition_variable::~condition_variable ( )

Destruct the condition variable object instance.

Member Function Documentation

◆ broadcast()

result_t os::rtos::condition_variable::broadcast ( void  )

Notify all threads waiting for a condition variable.

Parameters
None.
Return values
result::okAll waiting threads signalled.
EPERMCannot be invoked from an Interrupt Service Routines.
Errors
The function shall not fail with an error code of EINTR.

◆ name()

const char * os::rtos::internal::object_named::name ( void  ) const
inlineinherited

Get object name.

Parameters
None.
Returns
A null terminated string.

All objects return a non-null string; anonymous objects return "-".

Note
Can be invoked from Interrupt Service Routines.

Definition at line 759 of file os-decls.h.

◆ operator delete()

void os::rtos::internal::object_named_system::operator delete ( void *  ptr,
std::size_t  bytes 
)
inlinestaticinherited

Deallocate the dynamically allocated object instance. using the RTOS system allocator.

Parameters
ptrPointer to object.
bytesNumber of bytes to deallocate.
Returns
Nothing.

The deallocation function (3.7.4.2) called by a delete-expression to render the value of ptr invalid.

ptr shall be a null pointer or its value shall be a value returned by an earlier call to the (possibly replaced) operator new() which has not been invalidated by an intervening call to operator delete(void*).

If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the earlier call to operator new.

The storage is deallocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 122 of file os-inlines.h.

◆ operator delete[]()

void os::rtos::internal::object_named_system::operator delete[] ( void *  ptr,
std::size_t  bytes 
)
inlinestaticinherited

Deallocate the dynamically allocated array of object. instances using the RTOS system allocator.

Parameters
ptrPointer to array of objects.
bytesNumber of bytes to deallocate.
Returns
Nothing.

The deallocation function (3.7.4.2) called by the array form of a delete-expression to render the value of ptr invalid.

If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the earlier call to operator new.

The storage is deallocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 143 of file os-inlines.h.

◆ operator new() [1/2]

void * os::rtos::internal::object_named_system::operator new ( std::size_t  bytes)
inlinestaticinherited

Allocate space for a new object instance using the RTOS system allocator.

Parameters
bytesNumber of bytes to allocate.
Returns
Pointer to allocated object.

The allocation function (3.7.4.1) called by a new-expression (5.3.4) to allocate a storage of size bytes suitably aligned to represent any object of that size. Return a non-null pointer to suitably aligned storage (3.7.4).

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 44 of file os-inlines.h.

◆ operator new() [2/2]

void * os::rtos::internal::object_named_system::operator new ( std::size_t  bytes,
void *  ptr 
)
inlinestaticinherited

Emplace a new object instance.

Parameters
bytesNumber of bytes to emplace.
ptrPointer to location to emplace the object.
Returns
Pointer to emplaced object.

The allocation function (3.7.4.1) called by a placement new-expression to allocate a storage of size bytes suitably aligned to represent any object of that size. Return a non-null pointer to suitably aligned storage (3.7.4).

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 81 of file os-inlines.h.

◆ operator new[]() [1/2]

void * os::rtos::internal::object_named_system::operator new[] ( std::size_t  bytes)
inlinestaticinherited

Allocate space for an array of new object instances using the RTOS system allocator.

Parameters
bytesNumber of bytes to allocate.
Returns
Pointer to allocated array.

The allocation function (3.7.4.1) called by the array form of a new-expression (5.3.4) to allocate a storage of size bytes suitably aligned to represent any array object of that size or smaller.

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 62 of file os-inlines.h.

◆ operator new[]() [2/2]

void * os::rtos::internal::object_named_system::operator new[] ( std::size_t  bytes,
void *  ptr 
)
inlinestaticinherited

Emplace an array of new object instances.

Parameters
bytesNumber of bytes to emplace.
ptrPointer to location to emplace the object.
Returns
Pointer to emplaced array.

The allocation function (3.7.4.1) called by the array form of a placement new-expression to allocate a storage of size bytes suitably aligned to represent any array object of that size or smaller.

The storage is allocated using the RTOS system allocator.

Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 98 of file os-inlines.h.

◆ operator==()

bool os::rtos::condition_variable::operator== ( const condition_variable rhs) const
inline

Compare condition variables.

Return values
trueThe given condition variable is the same as this condition variable.
falseThe condition variables are different.

Identical condition variables should have the same memory address.

Definition at line 319 of file os-condvar.h.

◆ signal()

result_t os::rtos::condition_variable::signal ( void  )

Notify one thread waiting for a condition variable.

Parameters
None.
Return values
result::okThe thread was signalled.
EPERMCannot be invoked from an Interrupt Service Routines.
Errors
The function shall not fail with an error code of EINTR.

◆ timed_wait()

result_t os::rtos::condition_variable::timed_wait ( mutex mutex,
clock::duration_t  timeout 
)

Timed wait for a condition variable to be notified.

Parameters
[in]mutexReference to the associated mutex.
[in]timeoutTimeout to wait.
Return values
result::okThe condition change was signalled.
EPERMCannot be invoked from an Interrupt Service Routines, or the mutex type is mutex::type::errorcheck or the mutex is a robust mutex, and the current thread does not own the mutex.
ENOTRECOVERABLEThe state protected by the mutex is not recoverable.
EOWNERDEADThe mutex is a robust mutex and the process containing the previous owning thread terminated while holding the mutex lock. The mutex lock shall be acquired by the calling thread and it is up to the new owner to make the state consistent.
ETIMEDOUTThe timeout has passed.
Errors
The function shall not fail with an error code of EINTR.

◆ wait()

result_t os::rtos::condition_variable::wait ( mutex mutex)

Wait for a condition variable to be notified.

Parameters
[in]mutexReference to the associated mutex.
Return values
result::okThe condition change was signalled.
EPERMCannot be invoked from an Interrupt Service Routines, or the mutex type is mutex::type::errorcheck or the mutex is a robust mutex, and the current thread does not own the mutex.
ENOTRECOVERABLEThe state protected by the mutex is not recoverable.
EOWNERDEADThe mutex is a robust mutex and the process containing the previous owning thread terminated while holding the mutex lock. The mutex lock shall be acquired by the calling thread and it is up to the new owner to make the state consistent.
Errors
The function shall not fail with an error code of EINTR.

The documentation for this class was generated from the following files: