|
| 1 | +.. _condvar: |
| 2 | + |
| 3 | +Condition ariables |
| 4 | +#################### |
| 5 | + |
| 6 | +A :dfn:`condition variable` is a synchronization primitive |
| 7 | +that enables threads to wait until a particular condition occurs. |
| 8 | + |
| 9 | +.. contents:: |
| 10 | + :local: |
| 11 | + :depth: 2 |
| 12 | + |
| 13 | +Concepts |
| 14 | +******** |
| 15 | + |
| 16 | +Any number of condition variables can be defined (limited only by available RAM). Each |
| 17 | +condition variable is referenced by its memory address. |
| 18 | + |
| 19 | +To wait for a condition to become true, a thread can make use of a condition |
| 20 | +variable. |
| 21 | + |
| 22 | +A condition variable is basically a queue of threads that threads can put |
| 23 | +themselves on when some state of execution (i.e., some condition) is not as |
| 24 | +desired (by waiting on the condition). The function |
| 25 | +:c:func:`k_condvar_wait` performs atomically the following steps; |
| 26 | + |
| 27 | +# Releases the last acquired mutex. |
| 28 | +# Puts the current thread in the condition variable queue. |
| 29 | + |
| 30 | +Some other thread, when it changes said state, can then wake one (or more) |
| 31 | +of those waiting threads and thus allow them to continue by signaling on |
| 32 | +the condition using :c:func:`k_condvar_signal` or |
| 33 | +:c:func:`k_condvar_broadcast` then it: |
| 34 | + |
| 35 | +# Re-acquires the mutex previously released. |
| 36 | +# Returns from :c:func:`k_condvar_wait`. |
| 37 | + |
| 38 | +A condition variable must be initialized before it can be used. |
| 39 | + |
| 40 | + |
| 41 | +Implementation |
| 42 | +************** |
| 43 | + |
| 44 | +Defining a Condition Variable |
| 45 | +============================= |
| 46 | + |
| 47 | +A condition variable is defined using a variable of type :c:struct:`k_condvar`. |
| 48 | +It must then be initialized by calling :c:func:`k_condvar_init`. |
| 49 | + |
| 50 | +The following code defines a condition variable: |
| 51 | + |
| 52 | +.. code-block:: c |
| 53 | +
|
| 54 | + struct k_condvar my_condvar; |
| 55 | +
|
| 56 | + k_condvar_init(&my_condvar); |
| 57 | +
|
| 58 | +Alternatively, a condition variable can be defined and initialized at compile time |
| 59 | +by calling :c:macro:`K_CONDVAR_DEFINE`. |
| 60 | + |
| 61 | +The following code has the same effect as the code segment above. |
| 62 | + |
| 63 | +.. code-block:: c |
| 64 | +
|
| 65 | + K_CONDVAR_DEFINE(my_condvar); |
| 66 | +
|
| 67 | +Waiting on a Condition Variable |
| 68 | +=============================== |
| 69 | + |
| 70 | +A thread can wait on a condition by calling :c:func:`k_condvar_wait`. |
| 71 | + |
| 72 | +The following code waits on the condition variable. |
| 73 | + |
| 74 | + |
| 75 | +.. code-block:: c |
| 76 | +
|
| 77 | + K_MUTEX_DEFINE(mutex); |
| 78 | + K_CONDVAR_DEFINE(condvar) |
| 79 | +
|
| 80 | + void main(void) |
| 81 | + { |
| 82 | + k_mutex_lock(&mutex, K_FOREVER); |
| 83 | +
|
| 84 | + /* block this thread until another thread signals cond. While |
| 85 | + * blocked, the mutex is released, then re-acquired before this |
| 86 | + * thread is woken up and the call returns. |
| 87 | + */ |
| 88 | + k_condvar_wait(&condvar, &mutex, K_FOREVER); |
| 89 | + ... |
| 90 | + k_mutex_unlock(&mutex); |
| 91 | + } |
| 92 | +
|
| 93 | +Signaling a Condition Variable |
| 94 | +=============================== |
| 95 | + |
| 96 | +A condition variable is signaled on by calling :c:func:`k_condvar_signal` for |
| 97 | +one thread or by calling :c:func:`k_condvar_broadcast` for multiple threads. |
| 98 | + |
| 99 | +The following code builds on the example above. |
| 100 | + |
| 101 | +.. code-block:: c |
| 102 | +
|
| 103 | + void worker_thread(void) |
| 104 | + { |
| 105 | + k_mutex_lock(&mutex, K_FOREVER); |
| 106 | +
|
| 107 | + /* |
| 108 | + * Do some work and fullfill the condition |
| 109 | + */ |
| 110 | + ... |
| 111 | + ... |
| 112 | + k_condvar_signal(&condvar); |
| 113 | + k_mutex_unlock(&mutex); |
| 114 | + } |
| 115 | +
|
| 116 | +Suggested Uses |
| 117 | +************** |
| 118 | + |
| 119 | +Use condition variables with a mutex to signal changing states (conditions) from |
| 120 | +one thread to another thread. |
| 121 | +Condition variables are not the condition itself and they are not events. |
| 122 | +The condition is contained in the surrounding programming logic. |
| 123 | + |
| 124 | +Mutexes alone are not designed for use as a notification/synchronization |
| 125 | +mechanism. They are meant to provide mutually exclusive access to a shared |
| 126 | +resource only. |
| 127 | + |
| 128 | +Configuration Options |
| 129 | +********************* |
| 130 | + |
| 131 | +Related configuration options: |
| 132 | + |
| 133 | +* None. |
| 134 | + |
| 135 | +API Reference |
| 136 | +************** |
| 137 | + |
| 138 | +.. doxygengroup:: condvar_apis |
| 139 | + :project: Zephyr |
0 commit comments