Condition variable support. More...
Data Structures | |
struct | _CONDITION |
Condition variable. More... | |
Typedefs | |
typedef struct _CONDITION | CONDITION |
Condition variable type. | |
Functions | |
int | NutConditionInit (CONDITION *cond) |
Creates a new condition variable. | |
void | NutConditionLock (CONDITION *cond) |
Locks the condition mutex. | |
void | NutConditionUnlock (CONDITION *cond) |
Unocks the condition mutex. | |
int | NutConditionWait (CONDITION *cond) |
Waits until this thread is woken up on cond. | |
int | NutConditionSignal (CONDITION *cond) |
If threads are waiting for cond, exactly one of them is woken up. | |
int | NutConditionBroadcast (CONDITION *cond) |
If threads are waiting for cond, all of them are woken up. | |
void | NutConditionFree (CONDITION *cond) |
Free the ressources used by this condition variable. | |
int | NutConditionTimedWait (CONDITION *cond, uint32_t abs_ms) |
Waits until this thread is woken up on cond but not longer than until the time specified by abs_ms. |
Condition variable support.
To avoid entering a busy waiting state, threads must be able to signal each other about events of interest. This capability is implemented as condition variables. When a function requires a particular condition to be true before it can proceed, it waits on an associated condition variable. By waiting, it gives up the lock and is removed from the set of runnable threads. Any thread that subsequently causes the condition to be true may then use the condition variable to notify a thread waiting for the condition. A thread that has been notified regains the lock and can proceed.
As an example look to the following code:
CONDITION cond = NULL; int *current_data = NULL; void push_data (int *data) { NutConditionLock(cond); current_data = data; NutSonditionSignal(cond); NutConditionUnlock(cond); } int* pop_data (void) { int* data; NutConditionLock(cond); while (!current_data) { g_cond_wait(cond); } data = current_data; current_data = NULL; NutConditionUnlock(cond); return data; }
typedef struct _CONDITION CONDITION |
Condition variable type.
int NutConditionInit | ( | CONDITION * | cond | ) |
Creates a new condition variable.
References _CONDITION::mutex, NULL, NutHeapAlloc, and NutMutexInit().
void NutConditionLock | ( | CONDITION * | cond | ) |
Locks the condition mutex.
To avoid the "lost wakeup" bug it is important to always lock the condition before modifying the condition or signalling the condition variable
cond | The condition to be locked |
References _CONDITION::mutex, NULL, and NutMutexLock().
void NutConditionUnlock | ( | CONDITION * | cond | ) |
Unocks the condition mutex.
Always unlock the confition after modifying the condition and signalling the condition variable.
cond | The condition to be unlocked |
References _CONDITION::mutex, NULL, and NutMutexUnlock().
int NutConditionWait | ( | CONDITION * | cond | ) |
Waits until this thread is woken up on cond.
The condition is unlocked before falling asleep and locked again before resuming.
It is important to use the NutConditionWait() and NutConditionTimedWait() functions only inside a loop which checks for the condition to be true. It is not guaranteed that the waiting thread will find the condition fulfilled after it wakes up, even if the signaling thread left the condition in that state: another thread may have altered the condition before the waiting thread got the chance to be woken up, even if the condition itself is protected by locking with NutConditionLock.
Always lock the condition before entering the above mentioned check loop and always unlock the condition after successfully leaving the loop and processing the data you wait for.
cond | The condition to wait on. |
References _CONDITION::event, _CONDITION::mutex, NULL, NUT_WAIT_INFINITE, NutEventWait(), NutMutexLock(), and NutMutexUnlock().
int NutConditionSignal | ( | CONDITION * | cond | ) |
If threads are waiting for cond, exactly one of them is woken up.
Call this function after you fullfilled the condition. The conditon should be locked befor fulfilling the condition should not be unlocked before calling this function.
cond | The condition to signal |
References _CONDITION::event, NULL, and NutEventPost().
int NutConditionBroadcast | ( | CONDITION * | cond | ) |
If threads are waiting for cond, all of them are woken up.
Call this function after you fullfilled the condition. The conditon should be locked befor fulfilling the condition should not be unlocked before calling this function.
cond | The condition to signal |
References _CONDITION::event, NULL, and NutEventBroadcast().
void NutConditionFree | ( | CONDITION * | cond | ) |
Free the ressources used by this condition variable.
cond | Pointer to the condition |
References _CONDITION::mutex, NULL, NutHeapFree, and NutMutexDestroy().
Waits until this thread is woken up on cond but not longer than until the time specified by abs_ms.
The condition is unlocked before falling asleep and locked again before resuming.
It is important to use the NutConditionWait() and NutConditionTimedWait() functions only inside a loop which checks for the condition to be true. It is not guaranteed that the waiting thread will find the condition fulfilled after it wakes up, even if the signaling thread left the condition in that state: another thread may have altered the condition before the waiting thread got the chance to be woken up, even if the condition itself is protected by locking with NutConditionLock.
Always lock the condition before entering the above mentioned check loop and always unlock the condition after successfully leaving the loop and processing the data you wait for.
cond | The condition to wait on. |
abs_ms | Absolute time in ms to longest wait for. Use NutGetMillis() to obtain the current time and add your desired offset. Overflows are handled correct. At longest you can wait 2147483648ms |
References _CONDITION::event, _CONDITION::mutex, NULL, NutEventWait(), NutGetMillis(), NutMutexLock(), and NutMutexUnlock().