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 } else if (events[1].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) { 191 data = k_fifo_get(events[1].fifo, 0); 192 // handle data 193 } else if (events[2].state == K_POLL_STATE_MSGQ_DATA_AVAILABLE) { 194 ret = k_msgq_get(events[2].msgq, buf, K_NO_WAIT); 195 // handle data 196 } else if (events[3].state == K_POLL_STATE_PIPE_DATA_AVAILABLE) { 197 ret = k_pipe_get(events[3].pipe, buf, bytes_to_read, &bytes_read, min_xfer, K_NO_WAIT); 198 // handle data 199 } 200 events[0].state = K_POLL_STATE_NOT_READY; 201 events[1].state = K_POLL_STATE_NOT_READY; 202 events[2].state = K_POLL_STATE_NOT_READY; 203 events[3].state = K_POLL_STATE_NOT_READY; 204 } 205 } 206 207Using k_poll_signal_raise() 208=========================== 209 210One of the types of events is :c:macro:`K_POLL_TYPE_SIGNAL`: this is a "direct" 211signal to a poll event. This can be seen as a lightweight binary semaphore only 212one thread can wait for. 213 214A poll signal is a separate object of type :c:struct:`k_poll_signal` that 215must be attached to a k_poll_event, similar to a semaphore or FIFO. It must 216first be initialized either via :c:macro:`K_POLL_SIGNAL_INITIALIZER()` or 217:c:func:`k_poll_signal_init`. 218 219.. code-block:: c 220 221 struct k_poll_signal signal; 222 void do_stuff(void) 223 { 224 k_poll_signal_init(&signal); 225 } 226 227It is signaled via the :c:func:`k_poll_signal_raise` function. This function 228takes a user **result** parameter that is opaque to the API and can be used to 229pass extra information to the thread waiting on the event. 230 231.. code-block:: c 232 233 struct k_poll_signal signal; 234 235 // thread A 236 void do_stuff(void) 237 { 238 k_poll_signal_init(&signal); 239 240 struct k_poll_event events[1] = { 241 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, 242 K_POLL_MODE_NOTIFY_ONLY, 243 &signal), 244 }; 245 246 k_poll(events, 1, K_FOREVER); 247 248 int signaled, result; 249 250 k_poll_signal_check(&signal, &signaled, &result); 251 252 if (signaled && (result == 0x1337)) { 253 // A-OK! 254 } else { 255 // weird error 256 } 257 } 258 259 // thread B 260 void signal_do_stuff(void) 261 { 262 k_poll_signal_raise(&signal, 0x1337); 263 } 264 265If the signal is to be polled in a loop, *both* its event state must be 266reset to :c:macro:`K_POLL_STATE_NOT_READY` *and* its ``result`` must be 267reset using :c:func:`k_poll_signal_reset()` on each iteration if it has 268been signaled. 269 270.. code-block:: c 271 272 struct k_poll_signal signal; 273 void do_stuff(void) 274 { 275 k_poll_signal_init(&signal); 276 277 struct k_poll_event events[1] = { 278 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, 279 K_POLL_MODE_NOTIFY_ONLY, 280 &signal), 281 }; 282 283 for (;;) { 284 k_poll(events, 1, K_FOREVER); 285 286 int signaled, result; 287 288 k_poll_signal_check(&signal, &signaled, &result); 289 290 if (signaled && (result == 0x1337)) { 291 // A-OK! 292 } else { 293 // weird error 294 } 295 296 k_poll_signal_reset(signal); 297 events[0].state = K_POLL_STATE_NOT_READY; 298 } 299 } 300 301Note that poll signals are not internally synchronized. A :c:func:`k_poll` call 302that is passed a signal will return after any code in the system calls 303:c:func:`k_poll_signal_raise()`. But if the signal is being 304externally managed and reset via :c:func:`k_poll_signal_init()`, it is 305possible that by the time the application checks, the event state may 306no longer be equal to :c:macro:`K_POLL_STATE_SIGNALED`, and a (naive) 307application will miss events. Best practice is always to reset the 308signal only from within the thread invoking the :c:func:`k_poll` loop, or else 309to use some other event type which tracks event counts: semaphores and 310FIFOs are more error-proof in this sense because they can't "miss" 311events, architecturally. 312 313Suggested Uses 314************** 315 316Use :c:func:`k_poll` to consolidate multiple threads that would be pending 317on one object each, saving possibly large amounts of stack space. 318 319Use a poll signal as a lightweight binary semaphore if only one thread pends on 320it. 321 322.. note:: 323 Because objects are only signaled if no other thread is waiting for them to 324 become available and only one thread can poll on a specific object, polling 325 is best used when objects are not subject of contention between multiple 326 threads, basically when a single thread operates as a main "server" or 327 "dispatcher" for multiple objects and is the only one trying to acquire 328 these objects. 329 330Configuration Options 331********************* 332 333Related configuration options: 334 335* :kconfig:option:`CONFIG_POLL` 336 337API Reference 338************* 339 340.. doxygengroup:: poll_apis 341