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