POSIX compliant condition variable. More...
#include <cmsis-plus/rtos/os.h>
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. | |
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.
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.
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.
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.
pthread_cond_t
from <pthread.h>
(IEEE Std 1003.1, 2013 Edition). Definition at line 61 of file os-condvar.h.
os::rtos::condition_variable::condition_variable | ( | const attributes & | attr = initializer | ) |
Construct a condition variable object instance.
[in] | attr | Reference to attributes. |
EAGAIN
- The system lacked the necessary resources (other than memory) to create the condition variable.ENOMEM
- Insufficient memory exists to initialise the condition variable. 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.
pthread_cond_init()
from <pthread.h>
(IEEE Std 1003.1, 2013 Edition). Definition at line 238 of file os-condvar.cpp.
os::rtos::condition_variable::condition_variable | ( | const char * | name, |
const attributes & | attr = initializer |
||
) |
Construct a named condition variable object instance.
[in] | name | Pointer to name. |
[in] | attr | Reference to attributes. |
EAGAIN
- The system lacked the necessary resources (other than memory) to create the condition variable.ENOMEM
- Insufficient memory exists to initialise the condition variable. EINTR
. os::rtos::condition_variable::~condition_variable | ( | ) |
Destruct the condition variable object instance.
result_t os::rtos::condition_variable::broadcast | ( | void | ) |
Notify all threads waiting for a condition variable.
result::ok | All waiting threads signalled. |
EPERM | Cannot be invoked from an Interrupt Service Routines. |
EINTR
.
|
inlineinherited |
Get object name.
All objects return a non-null string; anonymous objects return "-"
.
Definition at line 774 of file os-decls.h.
|
inlinestaticinherited |
Deallocate the dynamically allocated object instance. using the RTOS system allocator.
ptr | Pointer to object. |
bytes | Number of bytes to deallocate. |
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.
Definition at line 137 of file os-inlines.h.
|
inlinestaticinherited |
Deallocate the dynamically allocated array of object. instances using the RTOS system allocator.
ptr | Pointer to array of objects. |
bytes | Number of bytes to deallocate. |
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.
Definition at line 158 of file os-inlines.h.
|
inlinestaticinherited |
Allocate space for a new object instance using the RTOS system allocator.
bytes | Number of bytes to allocate. |
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.
Definition at line 59 of file os-inlines.h.
|
inlinestaticinherited |
Emplace a new object instance.
bytes | Number of bytes to emplace. |
ptr | Pointer to location to emplace the 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.
Definition at line 96 of file os-inlines.h.
|
inlinestaticinherited |
Allocate space for an array of new object instances using the RTOS system allocator.
bytes | Number of bytes to allocate. |
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.
Definition at line 77 of file os-inlines.h.
|
inlinestaticinherited |
Emplace an array of new object instances.
bytes | Number of bytes to emplace. |
ptr | Pointer to location to emplace the object. |
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.
Definition at line 113 of file os-inlines.h.
|
inline |
Compare condition variables.
true | The given condition variable is the same as this condition variable. |
false | The condition variables are different. |
Identical condition variables should have the same memory address.
Definition at line 336 of file os-condvar.h.
result_t os::rtos::condition_variable::signal | ( | void | ) |
Notify one thread waiting for a condition variable.
result::ok | The thread was signalled. |
EPERM | Cannot be invoked from an Interrupt Service Routines. |
EINTR
. result_t os::rtos::condition_variable::timed_wait | ( | mutex & | mutex, |
clock::duration_t | timeout | ||
) |
Timed wait for a condition variable to be notified.
[in] | mutex | Reference to the associated mutex. |
[in] | timeout | Timeout to wait. |
result::ok | The condition change was signalled. |
EPERM | Cannot 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. |
ENOTRECOVERABLE | The state protected by the mutex is not recoverable. |
EOWNERDEAD | The 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. |
ETIMEDOUT | The timeout has passed. |
EINTR
. Wait for a condition variable to be notified.
[in] | mutex | Reference to the associated mutex. |
result::ok | The condition change was signalled. |
EPERM | Cannot 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. |
ENOTRECOVERABLE | The state protected by the mutex is not recoverable. |
EOWNERDEAD | The 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. |
EINTR
.