1.. _polling_v2: 2 3Polling API 4########### 5 6The polling API is used to wait concurrently for any one of multiple conditions 7to be fulfilled. 8 9.. contents:: 10 :local: 11 :depth: 2 12 13Concepts 14******** 15 16The polling API's main function is :c:func:`k_poll`, which is very similar 17in concept to the POSIX :c:func:`poll` function, except that it operates on 18kernel objects rather than on file descriptors. 19 20The polling API allows a single thread to wait concurrently for one or more 21conditions to be fulfilled without actively looking at each one individually. 22 23There is a limited set of such conditions: 24 25- a semaphore becomes available 26- a kernel FIFO contains data ready to be retrieved 27- a kernel message queue contains data ready to be retrieved 28- a kernel pipe contains data ready to be retrieved 29- a poll signal is raised 30 31A thread that wants to wait on multiple conditions must define an array of 32**poll events**, one for each condition. 33 34All events in the array must be initialized before the array can be polled on. 35 36Each event must specify which **type** of condition must be satisfied so that 37its state is changed to signal the requested condition has been met. 38 39Each event must specify what **kernel object** it wants the condition to be 40satisfied. 41 42Each event must specify which **mode** of operation is used when the condition 43is satisfied. 44 45Each event can optionally specify a **tag** to group multiple events together, 46to the user's discretion. 47 48Apart from the kernel objects, there is also a **poll signal** pseudo-object 49type that be directly signaled. 50 51The :c:func:`k_poll` function returns as soon as one of the conditions it 52is waiting for is fulfilled. It is possible for more than one to be fulfilled 53when :c:func:`k_poll` returns, if they were fulfilled before 54:c:func:`k_poll` was called, or due to the preemptive multi-threading 55nature of the kernel. The caller must look at the state of all the poll events 56in the array to figure out which ones were fulfilled and what actions to take. 57 58Currently, there is only one mode of operation available: the object is not 59acquired. As an example, this means that when :c:func:`k_poll` returns and 60the poll event states that the semaphore is available, the caller of 61:c:func:`k_poll()` must then invoke :c:func:`k_sem_take` to take 62ownership of the semaphore. If the semaphore is contested, there is no 63guarantee that it will be still available when :c:func:`k_sem_take` is 64called. 65 66Implementation 67************** 68 69Using k_poll() 70============== 71 72The main API is :c:func:`k_poll`, which operates on an array of poll events 73of type :c:struct:`k_poll_event`. Each entry in the array represents one 74event a call to :c:func:`k_poll` will wait for its condition to be 75fulfilled. 76 77Poll events can be initialized using either the runtime initializers 78:c:macro:`K_POLL_EVENT_INITIALIZER()` or :c:func:`k_poll_event_init`, or 79the static initializer :c:macro:`K_POLL_EVENT_STATIC_INITIALIZER()`. An object 80that matches the **type** specified must be passed to the initializers. The 81**mode** *must* be set to :c:enumerator:`K_POLL_MODE_NOTIFY_ONLY`. The state 82*must* be set to :c:macro:`K_POLL_STATE_NOT_READY` (the initializers take care 83of this). The user **tag** is optional and completely opaque to the API: it is 84there to help a user to group similar events together. Being optional, it is 85passed to the static initializer, but not the runtime ones for performance 86reasons. If using runtime initializers, the user must set it separately in the 87:c:struct:`k_poll_event` data structure. If an event in the array is to be 88ignored, most likely temporarily, its type can be set to 89:c:macro:`K_POLL_TYPE_IGNORE`. 90 91.. code-block:: c 92 93 struct k_poll_event events[4] = { 94 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE, 95 K_POLL_MODE_NOTIFY_ONLY, 96 &my_sem, 0), 97 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, 98 K_POLL_MODE_NOTIFY_ONLY, 99 &my_fifo, 0), 100 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE, 101 K_POLL_MODE_NOTIFY_ONLY, 102 &my_msgq, 0), 103 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_PIPE_DATA_AVAILABLE, 104 K_POLL_MODE_NOTIFY_ONLY, 105 &my_pipe, 0), 106 }; 107 108or at runtime 109 110.. code-block:: c 111 112 struct k_poll_event events[4]; 113 void some_init(void) 114 { 115 k_poll_event_init(&events[0], 116 K_POLL_TYPE_SEM_AVAILABLE, 117 K_POLL_MODE_NOTIFY_ONLY, 118 &my_sem); 119 120 k_poll_event_init(&events[1], 121 K_POLL_TYPE_FIFO_DATA_AVAILABLE, 122 K_POLL_MODE_NOTIFY_ONLY, 123 &my_fifo); 124 125 k_poll_event_init(&events[2], 126 K_POLL_TYPE_MSGQ_DATA_AVAILABLE, 127 K_POLL_MODE_NOTIFY_ONLY, 128 &my_msgq); 129 130 k_poll_event_init(&events[3], 131 K_POLL_TYPE_PIPE_DATA_AVAILABLE, 132 K_POLL_MODE_NOTIFY_ONLY, 133 &my_pipe); 134 135 // tags are left uninitialized if unused 136 } 137 138 139After the events are initialized, the array can be passed to 140:c:func:`k_poll`. A timeout can be specified to wait only for a specified 141amount of time, or the special values :c:macro:`K_NO_WAIT` and 142:c:macro:`K_FOREVER` to either not wait or wait until an event condition is 143satisfied and not sooner. 144 145A list of pollers is offered on each semaphore or FIFO and as many events 146can wait in it as the app wants. 147Notice that the waiters will be served in first-come-first-serve order, 148not in priority order. 149 150In case of success, :c:func:`k_poll` returns 0. If it times out, it returns 151-:c:macro:`EAGAIN`. 152 153.. code-block:: c 154 155 // assume there is no contention on this semaphore and FIFO 156 // -EADDRINUSE will not occur; the semaphore and/or data will be available 157 158 void do_stuff(void) 159 { 160 rc = k_poll(events, ARRAY_SIZE(events), K_MSEC(1000)); 161 if (rc == 0) { 162 if (events[0].state == K_POLL_STATE_SEM_AVAILABLE) { 163 k_sem_take(events[0].sem, 0); 164 } else if (events[1].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) { 165 data = k_fifo_get(events[1].fifo, 0); 166 // handle data 167 } else if (events[2].state == K_POLL_STATE_MSGQ_DATA_AVAILABLE) { 168 ret = k_msgq_get(events[2].msgq, buf, K_NO_WAIT); 169 // handle data 170 } else if (events[3].state == K_POLL_STATE_PIPE_DATA_AVAILABLE) { 171 ret = k_pipe_get(events[3].pipe, buf, bytes_to_read, &bytes_read, min_xfer, K_NO_WAIT); 172 // handle data 173 } 174 } else { 175 // handle timeout 176 } 177 } 178 179When :c:func:`k_poll` is called in a loop, the events state must be reset 180to :c:macro:`K_POLL_STATE_NOT_READY` by the user. 181 182.. code-block:: c 183 184 void do_stuff(void) 185 { 186 for(;;) { 187 rc = k_poll(events, ARRAY_SIZE(events), K_FOREVER); 188 if (events[0].state == K_POLL_STATE_SEM_AVAILABLE) { 189 k_sem_take(events[0].sem, 0); 190 } 191 if (events[1].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) { 192 data = k_fifo_get(events[1].fifo, 0); 193 // handle data 194 } 195 if (events[2].state == K_POLL_STATE_MSGQ_DATA_AVAILABLE) { 196 ret = k_msgq_get(events[2].msgq, buf, K_NO_WAIT); 197 // handle data 198 } 199 if (events[3].state == K_POLL_STATE_PIPE_DATA_AVAILABLE) { 200 ret = k_pipe_get(events[3].pipe, buf, bytes_to_read, &bytes_read, min_xfer, K_NO_WAIT); 201 // handle data 202 } 203 events[0].state = K_POLL_STATE_NOT_READY; 204 events[1].state = K_POLL_STATE_NOT_READY; 205 events[2].state = K_POLL_STATE_NOT_READY; 206 events[3].state = K_POLL_STATE_NOT_READY; 207 } 208 } 209 210Using k_poll_signal_raise() 211=========================== 212 213One of the types of events is :c:macro:`K_POLL_TYPE_SIGNAL`: this is a "direct" 214signal to a poll event. This can be seen as a lightweight binary semaphore only 215one thread can wait for. 216 217A poll signal is a separate object of type :c:struct:`k_poll_signal` that 218must be attached to a k_poll_event, similar to a semaphore or FIFO. It must 219first be initialized either via :c:macro:`K_POLL_SIGNAL_INITIALIZER()` or 220:c:func:`k_poll_signal_init`. 221 222.. code-block:: c 223 224 struct k_poll_signal signal; 225 void do_stuff(void) 226 { 227 k_poll_signal_init(&signal); 228 } 229 230It is signaled via the :c:func:`k_poll_signal_raise` function. This function 231takes a user **result** parameter that is opaque to the API and can be used to 232pass extra information to the thread waiting on the event. 233 234.. code-block:: c 235 236 struct k_poll_signal signal; 237 238 // thread A 239 void do_stuff(void) 240 { 241 k_poll_signal_init(&signal); 242 243 struct k_poll_event events[1] = { 244 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, 245 K_POLL_MODE_NOTIFY_ONLY, 246 &signal), 247 }; 248 249 k_poll(events, 1, K_FOREVER); 250 251 int signaled, result; 252 253 k_poll_signal_check(&signal, &signaled, &result); 254 255 if (signaled && (result == 0x1337)) { 256 // A-OK! 257 } else { 258 // weird error 259 } 260 } 261 262 // thread B 263 void signal_do_stuff(void) 264 { 265 k_poll_signal_raise(&signal, 0x1337); 266 } 267 268If the signal is to be polled in a loop, *both* its event state must be 269reset to :c:macro:`K_POLL_STATE_NOT_READY` *and* its ``result`` must be 270reset using :c:func:`k_poll_signal_reset()` on each iteration if it has 271been signaled. 272 273.. code-block:: c 274 275 struct k_poll_signal signal; 276 void do_stuff(void) 277 { 278 k_poll_signal_init(&signal); 279 280 struct k_poll_event events[1] = { 281 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, 282 K_POLL_MODE_NOTIFY_ONLY, 283 &signal), 284 }; 285 286 for (;;) { 287 k_poll(events, 1, K_FOREVER); 288 289 int signaled, result; 290 291 k_poll_signal_check(&signal, &signaled, &result); 292 293 if (signaled && (result == 0x1337)) { 294 // A-OK! 295 } else { 296 // weird error 297 } 298 299 k_poll_signal_reset(signal); 300 events[0].state = K_POLL_STATE_NOT_READY; 301 } 302 } 303 304Note that poll signals are not internally synchronized. A :c:func:`k_poll` call 305that is passed a signal will return after any code in the system calls 306:c:func:`k_poll_signal_raise()`. But if the signal is being 307externally managed and reset via :c:func:`k_poll_signal_init()`, it is 308possible that by the time the application checks, the event state may 309no longer be equal to :c:macro:`K_POLL_STATE_SIGNALED`, and a (naive) 310application will miss events. Best practice is always to reset the 311signal only from within the thread invoking the :c:func:`k_poll` loop, or else 312to use some other event type which tracks event counts: semaphores and 313FIFOs are more error-proof in this sense because they can't "miss" 314events, architecturally. 315 316Suggested Uses 317************** 318 319Use :c:func:`k_poll` to consolidate multiple threads that would be pending 320on one object each, saving possibly large amounts of stack space. 321 322Use a poll signal as a lightweight binary semaphore if only one thread pends on 323it. 324 325.. note:: 326 Because objects are only signaled if no other thread is waiting for them to 327 become available and only one thread can poll on a specific object, polling 328 is best used when objects are not subject of contention between multiple 329 threads, basically when a single thread operates as a main "server" or 330 "dispatcher" for multiple objects and is the only one trying to acquire 331 these objects. 332 333Configuration Options 334********************* 335 336Related configuration options: 337 338* :kconfig:option:`CONFIG_POLL` 339 340API Reference 341************* 342 343.. doxygengroup:: poll_apis 344