1 /*
2 * Copyright (c) 2017 Wind River Systems, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9
10 /* global values and data structures */
11 struct fifo_msg {
12 void *private;
13 uint32_t msg;
14 };
15
16 #define SIGNAL_RESULT 0x1ee7d00d
17 #define FIFO_MSG_VALUE 0xdeadbeef
18 #define MSGQ_MSG_SIZE 4
19 #define MSGQ_MAX_MSGS 16
20 #define MSGQ_MSG_VALUE {'a', 'b', 'c', 'd'}
21 #define PIPE_DATA "atad_epip"
22 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
23
24 /* verify k_poll() without waiting */
25 static struct k_sem no_wait_sem;
26 static struct k_fifo no_wait_fifo;
27 static struct k_poll_signal no_wait_signal;
28 K_PIPE_DEFINE(no_wait_pipe, 32, 1);
29 static struct k_poll_signal test_signal;
30 #ifndef CONFIG_USERSPACE
31 static struct k_msgq no_wait_msgq;
32 #endif
33 static struct k_sem zero_events_sem;
34 static struct k_thread test_thread;
35 static struct k_thread test_loprio_thread;
36 K_THREAD_STACK_DEFINE(test_stack, STACK_SIZE);
37 K_THREAD_STACK_DEFINE(test_loprio_stack, STACK_SIZE);
38 K_MSGQ_DEFINE(msgq_high_prio_thread, sizeof(unsigned int), 4, 4);
39 static K_THREAD_STACK_DEFINE(high_prio_stack_area, 4096);
40 static struct k_thread high_prio_data;
41 static volatile bool wake_up_by_poll = true;
42
43 /**
44 * @brief Test cases to verify poll
45 *
46 * @defgroup kernel_poll_tests Poll tests
47 *
48 * @ingroup all_tests
49 *
50 * @{
51 * @}
52 */
53
54 /**
55 * @brief Test poll events with no wait
56 *
57 * @ingroup kernel_poll_tests
58 *
59 * @see K_POLL_EVENT_INITIALIZER(), k_poll_signal_init(),
60 * k_poll_signal_raise(), k_poll_signal_check()
61 */
ZTEST_USER(poll_api_1cpu,test_poll_no_wait)62 ZTEST_USER(poll_api_1cpu, test_poll_no_wait)
63 {
64 struct fifo_msg msg = { NULL, FIFO_MSG_VALUE }, *msg_ptr;
65 unsigned int signaled;
66 char msgq_recv_buf[MSGQ_MSG_SIZE] = {0};
67 char msgq_msg[MSGQ_MSG_SIZE] = MSGQ_MSG_VALUE;
68 char pipe_recv_buf[sizeof(PIPE_DATA) + 4];
69 int result;
70 struct k_msgq *mq;
71 #ifdef CONFIG_USERSPACE
72 mq = k_object_alloc(K_OBJ_MSGQ);
73 zassert_not_null(mq, "");
74 #else
75 mq = &no_wait_msgq;
76 #endif
77
78 k_sem_init(&no_wait_sem, 1, 1);
79 k_fifo_init(&no_wait_fifo);
80 k_poll_signal_init(&no_wait_signal);
81
82 k_msgq_alloc_init(mq, MSGQ_MSG_SIZE, MSGQ_MAX_MSGS);
83
84 k_pipe_write(&no_wait_pipe, PIPE_DATA, sizeof(PIPE_DATA), K_NO_WAIT);
85
86 struct k_poll_event events[] = {
87 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
88 K_POLL_MODE_NOTIFY_ONLY,
89 &no_wait_sem),
90 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
91 K_POLL_MODE_NOTIFY_ONLY,
92 &no_wait_fifo),
93 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
94 K_POLL_MODE_NOTIFY_ONLY,
95 &no_wait_signal),
96 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_IGNORE,
97 K_POLL_MODE_NOTIFY_ONLY,
98 NULL),
99 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
100 K_POLL_MODE_NOTIFY_ONLY,
101 mq),
102 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_PIPE_DATA_AVAILABLE,
103 K_POLL_MODE_NOTIFY_ONLY,
104 &no_wait_pipe),
105 };
106
107 #ifdef CONFIG_USERSPACE
108 /* Test that k_poll() syscall handler safely handles being
109 * fed garbage
110 *
111 * TODO: Where possible migrate these to the main k_poll()
112 * implementation
113 */
114
115 zassert_equal(k_poll(events, INT_MAX, K_NO_WAIT), -EINVAL);
116 zassert_equal(k_poll(events, 4096, K_NO_WAIT), -ENOMEM);
117
118 /* Allow zero events */
119 zassert_equal(k_poll(events, 0, K_NO_WAIT), -EAGAIN);
120
121 struct k_poll_event bad_events[] = {
122 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
123 K_POLL_NUM_MODES,
124 &no_wait_sem),
125 };
126 zassert_equal(k_poll(bad_events, ARRAY_SIZE(bad_events), K_NO_WAIT),
127 -EINVAL,
128 NULL);
129
130 /* can't use the initializer to misconstruct this */
131 struct k_poll_event bad_events2[] = {
132 { .type = 0xFU,
133 .state = K_POLL_STATE_NOT_READY,
134 .mode = K_POLL_MODE_NOTIFY_ONLY,
135 .obj = &no_wait_sem,
136 },
137 };
138 zassert_equal(k_poll(bad_events2, ARRAY_SIZE(bad_events), K_NO_WAIT),
139 -EINVAL,
140 NULL);
141 #endif /* CONFIG_USERSPACE */
142
143 /* test polling events that are already ready */
144 zassert_false(k_fifo_alloc_put(&no_wait_fifo, &msg));
145 k_poll_signal_raise(&no_wait_signal, SIGNAL_RESULT);
146 zassert_false(k_msgq_put(mq, msgq_msg, K_NO_WAIT));
147
148 zassert_equal(k_poll(events, ARRAY_SIZE(events), K_NO_WAIT), 0, "");
149
150 zassert_equal(events[0].state, K_POLL_STATE_SEM_AVAILABLE, "");
151 zassert_equal(k_sem_take(&no_wait_sem, K_NO_WAIT), 0, "");
152
153 zassert_equal(events[1].state, K_POLL_STATE_FIFO_DATA_AVAILABLE, "");
154 msg_ptr = k_fifo_get(&no_wait_fifo, K_NO_WAIT);
155 zassert_not_null(msg_ptr, "");
156 zassert_equal(msg_ptr, &msg, "");
157 zassert_equal(msg_ptr->msg, FIFO_MSG_VALUE, "");
158
159 zassert_equal(events[2].state, K_POLL_STATE_SIGNALED, "");
160 k_poll_signal_check(&no_wait_signal, &signaled, &result);
161 zassert_not_equal(signaled, 0, "");
162 zassert_equal(result, SIGNAL_RESULT, "");
163
164 zassert_equal(events[3].state, K_POLL_STATE_NOT_READY, "");
165
166 zassert_equal(events[4].state, K_POLL_STATE_MSGQ_DATA_AVAILABLE, "");
167 zassert_false(k_msgq_get(mq, msgq_recv_buf, K_NO_WAIT));
168 zassert_false(memcmp(msgq_msg, msgq_recv_buf, MSGQ_MSG_SIZE), "");
169
170 zassert_equal(events[5].state, K_POLL_STATE_PIPE_DATA_AVAILABLE);
171 result = k_pipe_read(&no_wait_pipe, pipe_recv_buf, sizeof(pipe_recv_buf), K_NO_WAIT);
172 zassert_equal(result, sizeof(PIPE_DATA));
173 zassert_str_equal(pipe_recv_buf, PIPE_DATA);
174
175 /* verify events are not ready anymore (user has to clear them first) */
176 events[0].state = K_POLL_STATE_NOT_READY;
177 events[1].state = K_POLL_STATE_NOT_READY;
178 events[2].state = K_POLL_STATE_NOT_READY;
179 events[3].state = K_POLL_STATE_NOT_READY;
180 events[4].state = K_POLL_STATE_NOT_READY;
181 events[5].state = K_POLL_STATE_NOT_READY;
182 k_poll_signal_reset(&no_wait_signal);
183
184 zassert_equal(k_poll(events, ARRAY_SIZE(events), K_NO_WAIT), -EAGAIN,
185 "");
186 zassert_equal(events[0].state, K_POLL_STATE_NOT_READY, "");
187 zassert_equal(events[1].state, K_POLL_STATE_NOT_READY, "");
188 zassert_equal(events[2].state, K_POLL_STATE_NOT_READY, "");
189 zassert_equal(events[3].state, K_POLL_STATE_NOT_READY, "");
190 zassert_equal(events[4].state, K_POLL_STATE_NOT_READY, "");
191 zassert_equal(events[5].state, K_POLL_STATE_NOT_READY, "");
192
193 zassert_not_equal(k_sem_take(&no_wait_sem, K_NO_WAIT), 0, "");
194 zassert_is_null(k_fifo_get(&no_wait_fifo, K_NO_WAIT), "");
195 zassert_not_equal(k_msgq_get(mq, msgq_recv_buf, K_NO_WAIT), 0, "");
196 }
197
198 /* verify k_poll() that has to wait */
199 static struct k_msgq wait_msgq;
200 static struct k_msgq *wait_msgq_ptr;
201
202 static K_SEM_DEFINE(wait_sem, 0, 1);
203 static K_FIFO_DEFINE(wait_fifo);
204 static struct k_poll_signal wait_signal =
205 K_POLL_SIGNAL_INITIALIZER(wait_signal);
206
207 struct fifo_msg wait_msg = { NULL, FIFO_MSG_VALUE };
208
209 K_PIPE_DEFINE(wait_pipe, 32, 1);
210
211 #define TAG_0 10
212 #define TAG_1 11
213 #define TAG_2 12
214 #define TAG_3 13
215 #define TAG_4 14
216
217 struct k_poll_event wait_events[] = {
218 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
219 K_POLL_MODE_NOTIFY_ONLY,
220 &wait_sem, TAG_0),
221 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
222 K_POLL_MODE_NOTIFY_ONLY,
223 &wait_fifo, TAG_1),
224 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SIGNAL,
225 K_POLL_MODE_NOTIFY_ONLY,
226 &wait_signal, TAG_2),
227 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_IGNORE,
228 K_POLL_MODE_NOTIFY_ONLY,
229 NULL),
230 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
231 K_POLL_MODE_NOTIFY_ONLY,
232 &wait_msgq, TAG_3),
233 K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_PIPE_DATA_AVAILABLE,
234 K_POLL_MODE_NOTIFY_ONLY,
235 &wait_pipe, TAG_4),
236 };
237
238 #define USE_FIFO (1 << 0)
239 #define USE_MSGQ (1 << 1)
240 #define USE_PIPE (1 << 2)
241
poll_wait_helper(void * use_queuelike,void * msgq,void * p3)242 static void poll_wait_helper(void *use_queuelike, void *msgq, void *p3)
243 {
244 (void)p3;
245
246 k_sleep(K_MSEC(250));
247
248 k_sem_give(&wait_sem);
249
250 uintptr_t flags = (uintptr_t)use_queuelike;
251
252 if (flags & USE_FIFO) {
253 k_fifo_alloc_put(&wait_fifo, &wait_msg);
254 }
255
256 k_poll_signal_raise(&wait_signal, SIGNAL_RESULT);
257
258 if (flags & USE_MSGQ) {
259 char m[] = MSGQ_MSG_VALUE;
260
261 k_msgq_put(msgq, &m[0], K_FOREVER);
262 }
263
264 if (flags & USE_PIPE) {
265 k_pipe_write(&wait_pipe, PIPE_DATA, sizeof(PIPE_DATA), K_NO_WAIT);
266 }
267 }
268
269 /* check results for multiple events */
check_results(struct k_poll_event * events,uint32_t event_type,bool is_available)270 void check_results(struct k_poll_event *events, uint32_t event_type,
271 bool is_available)
272 {
273 struct fifo_msg *msg_ptr;
274 char msgq_recv_buf[MSGQ_MSG_SIZE] = {0};
275 char msg[] = MSGQ_MSG_VALUE;
276 char pipe_recv_buf[sizeof(PIPE_DATA) + 4];
277 int result;
278
279 switch (event_type) {
280 case K_POLL_TYPE_SEM_AVAILABLE:
281 if (is_available) {
282 zassert_equal(events->state, K_POLL_STATE_SEM_AVAILABLE,
283 "");
284 zassert_equal(k_sem_take(&wait_sem, K_NO_WAIT), 0, "");
285 zassert_equal(events->tag, TAG_0, "");
286 /* reset to not ready */
287 events->state = K_POLL_STATE_NOT_READY;
288 } else {
289 zassert_equal(events->state, K_POLL_STATE_NOT_READY,
290 "");
291 zassert_equal(k_sem_take(&wait_sem, K_NO_WAIT), -EBUSY,
292 "");
293 zassert_equal(events->tag, TAG_0, "");
294 }
295 break;
296 case K_POLL_TYPE_DATA_AVAILABLE:
297 if (is_available) {
298 zassert_equal(events->state,
299 K_POLL_STATE_FIFO_DATA_AVAILABLE, "");
300 msg_ptr = k_fifo_get(&wait_fifo, K_NO_WAIT);
301 zassert_not_null(msg_ptr, "");
302 zassert_equal(msg_ptr, &wait_msg, "");
303 zassert_equal(msg_ptr->msg, FIFO_MSG_VALUE, "");
304 zassert_equal(events->tag, TAG_1, "");
305 /* reset to not ready */
306 events->state = K_POLL_STATE_NOT_READY;
307 } else {
308 zassert_equal(events->state, K_POLL_STATE_NOT_READY,
309 "");
310 }
311 break;
312 case K_POLL_TYPE_SIGNAL:
313 if (is_available) {
314 zassert_equal(wait_events[2].state,
315 K_POLL_STATE_SIGNALED, "");
316 zassert_equal(wait_signal.signaled, 1, "");
317 zassert_equal(wait_signal.result, SIGNAL_RESULT, "");
318 zassert_equal(wait_events[2].tag, TAG_2, "");
319 /* reset to not ready */
320 events->state = K_POLL_STATE_NOT_READY;
321 wait_signal.signaled = 0U;
322 } else {
323 zassert_equal(events->state, K_POLL_STATE_NOT_READY,
324 "");
325 }
326 break;
327 case K_POLL_TYPE_IGNORE:
328 zassert_equal(wait_events[3].state, K_POLL_STATE_NOT_READY, "");
329 break;
330 case K_POLL_TYPE_MSGQ_DATA_AVAILABLE:
331 if (is_available) {
332 zassert_equal(events->state,
333 K_POLL_STATE_MSGQ_DATA_AVAILABLE, "");
334
335 zassert_false(k_msgq_get(wait_msgq_ptr, msgq_recv_buf,
336 K_NO_WAIT), "");
337 zassert_false(memcmp(msg, msgq_recv_buf,
338 MSGQ_MSG_SIZE), "");
339 zassert_equal(events->tag, TAG_3, "");
340 /* reset to not ready */
341 events->state = K_POLL_STATE_NOT_READY;
342 } else {
343 zassert_equal(events->state, K_POLL_STATE_NOT_READY,
344 "");
345 }
346 break;
347 case K_POLL_TYPE_PIPE_DATA_AVAILABLE:
348 if (is_available) {
349 zassert_equal(events->state, K_POLL_STATE_PIPE_DATA_AVAILABLE);
350 result = k_pipe_read(&wait_pipe, pipe_recv_buf,
351 sizeof(pipe_recv_buf), K_NO_WAIT);
352 zassert_equal(result, sizeof(PIPE_DATA));
353 zassert_str_equal(pipe_recv_buf, PIPE_DATA);
354 zassert_equal(events->tag, TAG_4);
355 /* reset to not ready */
356 events->state = K_POLL_STATE_NOT_READY;
357 } else {
358 zassert_equal(events->state, K_POLL_STATE_NOT_READY);
359 }
360 break;
361 default:
362 __ASSERT(false, "invalid event type (0x%x)\n", event_type);
363 break;
364 }
365 }
366
367 /**
368 * @brief Test polling with wait
369 *
370 * @ingroup kernel_poll_tests
371 *
372 * @details
373 * Test Objective:
374 * - Test the poll operation which enables waiting concurrently
375 * for one/two/all conditions to be fulfilled.
376 * - set a single timeout argument indicating
377 * the maximum amount of time a thread shall wait.
378 *
379 * Testing techniques:
380 * - function and block box testing.
381 * - Interface testing.
382 * - Dynamic analysis and testing.
383 *
384 * Prerequisite Conditions:
385 * - CONFIG_TEST_USERSPACE
386 * - CONFIG_DYNAMIC_OBJECTS
387 * - CONFIG_POLL
388 *
389 * Input Specifications:
390 * - N/A
391 *
392 * Test Procedure:
393 * -# Use FIFO/semaphore/signal/message queue object to define poll event.
394 * -# Initialize the FIFO/semaphore/signal/message queue object.
395 * -# Create a thread to put FIFO,
396 * give semaphore, raise signal, and put message queue.
397 * -# Check the result when signal is raised,
398 * semaphore is given, fifo is filled, and message is received.
399 * -# Check the result when no event is satisfied.
400 * -# Check the result when only semaphore is given.
401 * -# Check the result when only FIFO is filled.
402 * -# Check the result when only signal is raised.
403 * -# Check the result when only message is received.
404 *
405 * Expected Test Result:
406 * - FIFO/semaphore/signal/message queue events available/waitable in poll.
407 *
408 * Pass/Fail Criteria:
409 * - Successful if check points in test procedure are all passed, otherwise failure.
410 *
411 * Assumptions and Constraints:
412 * - N/A
413 *
414 * @see k_poll_signal_init(), k_poll()
415 */
ZTEST(poll_api_1cpu,test_poll_wait)416 ZTEST(poll_api_1cpu, test_poll_wait)
417 {
418 const int main_low_prio = 10;
419
420 #ifdef CONFIG_USERSPACE
421 wait_msgq_ptr = k_object_alloc(K_OBJ_MSGQ);
422 k_msgq_alloc_init(wait_msgq_ptr, MSGQ_MSG_SIZE, MSGQ_MAX_MSGS);
423
424 k_poll_event_init(&wait_events[4],
425 K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
426 K_POLL_MODE_NOTIFY_ONLY,
427 wait_msgq_ptr);
428 wait_events[4].tag = TAG_3;
429 #else
430 wait_msgq_ptr = &wait_msgq;
431 k_msgq_alloc_init(wait_msgq_ptr, MSGQ_MSG_SIZE, MSGQ_MAX_MSGS);
432 #endif
433 int rc;
434
435 int old_prio = k_thread_priority_get(k_current_get());
436
437 k_poll_signal_init(&wait_signal);
438 /*
439 * Wait for 4 non-ready events to become ready from a higher priority
440 * thread.
441 */
442 k_thread_priority_set(k_current_get(), main_low_prio);
443
444 k_tid_t tid1 = k_thread_create(&test_thread, test_stack,
445 K_THREAD_STACK_SIZEOF(test_stack),
446 poll_wait_helper, (void *)(USE_FIFO | USE_MSGQ | USE_PIPE),
447 wait_msgq_ptr, 0, main_low_prio - 1,
448 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
449
450 rc = k_poll(wait_events, ARRAY_SIZE(wait_events), K_NO_WAIT);
451 zassert_equal(rc, -EAGAIN, "should return EAGAIN with K_NO_WAIT");
452
453 rc = k_poll(wait_events, ARRAY_SIZE(wait_events), K_SECONDS(1));
454
455 k_thread_priority_set(k_current_get(), old_prio);
456
457 zassert_equal(rc, 0, "");
458 /* all events should be available. */
459
460 check_results(&wait_events[0], K_POLL_TYPE_SEM_AVAILABLE, true);
461 check_results(&wait_events[1], K_POLL_TYPE_DATA_AVAILABLE, true);
462 check_results(&wait_events[2], K_POLL_TYPE_SIGNAL, true);
463 check_results(&wait_events[3], K_POLL_TYPE_IGNORE, true);
464 check_results(&wait_events[4], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, true);
465 check_results(&wait_events[5], K_POLL_TYPE_PIPE_DATA_AVAILABLE, true);
466
467 /* verify events are not ready anymore */
468 zassert_equal(k_poll(wait_events, ARRAY_SIZE(wait_events),
469 K_SECONDS(1)), -EAGAIN, "");
470 /* all events should not be available. */
471
472 check_results(&wait_events[0], K_POLL_TYPE_SEM_AVAILABLE, false);
473 check_results(&wait_events[1], K_POLL_TYPE_DATA_AVAILABLE, false);
474 check_results(&wait_events[2], K_POLL_TYPE_SIGNAL, false);
475 check_results(&wait_events[3], K_POLL_TYPE_IGNORE, false);
476 check_results(&wait_events[4], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, false);
477 check_results(&wait_events[5], K_POLL_TYPE_PIPE_DATA_AVAILABLE, false);
478
479 /*
480 * Wait for 2 out of 4 non-ready events to become ready from a higher
481 * priority thread.
482 */
483 k_thread_priority_set(k_current_get(), main_low_prio);
484
485 k_tid_t tid2 = k_thread_create(&test_thread, test_stack,
486 K_THREAD_STACK_SIZEOF(test_stack),
487 poll_wait_helper,
488 0, 0, 0, main_low_prio - 1, 0, K_NO_WAIT);
489
490 rc = k_poll(wait_events, ARRAY_SIZE(wait_events), K_SECONDS(1));
491
492 k_thread_priority_set(k_current_get(), old_prio);
493
494 zassert_equal(rc, 0, "");
495
496 check_results(&wait_events[0], K_POLL_TYPE_SEM_AVAILABLE, true);
497 check_results(&wait_events[1], K_POLL_TYPE_DATA_AVAILABLE, false);
498 check_results(&wait_events[2], K_POLL_TYPE_SIGNAL, true);
499 check_results(&wait_events[4], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, false);
500 check_results(&wait_events[4], K_POLL_TYPE_PIPE_DATA_AVAILABLE, false);
501
502 /*
503 * Wait for each event to be ready from a lower priority thread, one at
504 * a time.
505 */
506 k_tid_t tid3 = k_thread_create(&test_thread, test_stack,
507 K_THREAD_STACK_SIZEOF(test_stack),
508 poll_wait_helper,
509 (void *)(USE_FIFO | USE_MSGQ), wait_msgq_ptr, 0, old_prio + 1,
510 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
511 /* semaphore */
512 rc = k_poll(wait_events, ARRAY_SIZE(wait_events), K_SECONDS(1));
513 zassert_equal(rc, 0, "");
514
515 check_results(&wait_events[0], K_POLL_TYPE_SEM_AVAILABLE, true);
516 check_results(&wait_events[1], K_POLL_TYPE_DATA_AVAILABLE, false);
517 check_results(&wait_events[2], K_POLL_TYPE_SIGNAL, false);
518 check_results(&wait_events[4], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, false);
519 check_results(&wait_events[5], K_POLL_TYPE_PIPE_DATA_AVAILABLE, false);
520
521 /* fifo */
522 rc = k_poll(wait_events, ARRAY_SIZE(wait_events), K_SECONDS(1));
523
524 zassert_equal(rc, 0, "");
525
526 check_results(&wait_events[0], K_POLL_TYPE_SEM_AVAILABLE, false);
527 check_results(&wait_events[1], K_POLL_TYPE_DATA_AVAILABLE, true);
528 check_results(&wait_events[2], K_POLL_TYPE_SIGNAL, false);
529 check_results(&wait_events[4], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, false);
530 check_results(&wait_events[5], K_POLL_TYPE_PIPE_DATA_AVAILABLE, false);
531
532 /* poll signal */
533 rc = k_poll(wait_events, ARRAY_SIZE(wait_events), K_SECONDS(1));
534
535 zassert_equal(rc, 0, "");
536
537 check_results(&wait_events[0], K_POLL_TYPE_SEM_AVAILABLE, false);
538 check_results(&wait_events[1], K_POLL_TYPE_DATA_AVAILABLE, false);
539 check_results(&wait_events[2], K_POLL_TYPE_SIGNAL, true);
540 check_results(&wait_events[4], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, false);
541 check_results(&wait_events[5], K_POLL_TYPE_PIPE_DATA_AVAILABLE, false);
542
543 /* message queue */
544 rc = k_poll(wait_events, ARRAY_SIZE(wait_events), K_SECONDS(1));
545
546 zassert_equal(rc, 0, "");
547
548 check_results(&wait_events[0], K_POLL_TYPE_SEM_AVAILABLE, false);
549 check_results(&wait_events[1], K_POLL_TYPE_DATA_AVAILABLE, false);
550 check_results(&wait_events[2], K_POLL_TYPE_SIGNAL, false);
551 check_results(&wait_events[4], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, true);
552 check_results(&wait_events[5], K_POLL_TYPE_PIPE_DATA_AVAILABLE, false);
553
554 k_thread_abort(tid1);
555 k_thread_abort(tid2);
556 k_thread_abort(tid3);
557 }
558
559 /* verify k_poll() that waits on object which gets cancellation */
560
561 static struct k_fifo cancel_fifo;
562 static struct k_fifo non_cancel_fifo;
563
poll_cancel_helper(void * p1,void * p2,void * p3)564 static void poll_cancel_helper(void *p1, void *p2, void *p3)
565 {
566 (void)p1; (void)p2; (void)p3;
567
568 static struct fifo_msg msg;
569
570 k_sleep(K_MSEC(100));
571
572 k_fifo_cancel_wait(&cancel_fifo);
573
574 k_fifo_alloc_put(&non_cancel_fifo, &msg);
575 }
576
577 /**
578 * @brief Test polling of cancelled fifo
579 *
580 * @details Test the FIFO(queue) data available/cancelable events
581 * as events in poll.
582 *
583 * @ingroup kernel_poll_tests
584 *
585 * @see k_poll(), k_fifo_cancel_wait(), k_fifo_alloc_put
586 */
test_poll_cancel(bool is_main_low_prio)587 void test_poll_cancel(bool is_main_low_prio)
588 {
589 const int main_low_prio = 10;
590 int old_prio = k_thread_priority_get(k_current_get());
591 int rc;
592
593 struct k_poll_event cancel_events[] = {
594 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
595 K_POLL_MODE_NOTIFY_ONLY,
596 &cancel_fifo),
597 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
598 K_POLL_MODE_NOTIFY_ONLY,
599 &non_cancel_fifo),
600 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_IGNORE,
601 K_POLL_MODE_NOTIFY_ONLY,
602 NULL),
603 };
604
605 k_fifo_init(&cancel_fifo);
606 k_fifo_init(&non_cancel_fifo);
607
608 if (is_main_low_prio) {
609 k_thread_priority_set(k_current_get(), main_low_prio);
610 }
611
612 k_tid_t tid = k_thread_create(&test_thread, test_stack,
613 K_THREAD_STACK_SIZEOF(test_stack),
614 poll_cancel_helper, (void *)1, 0, 0,
615 main_low_prio - 1, K_USER | K_INHERIT_PERMS,
616 K_NO_WAIT);
617
618 rc = k_poll(cancel_events, ARRAY_SIZE(cancel_events), K_SECONDS(1));
619
620 k_thread_priority_set(k_current_get(), old_prio);
621
622 zassert_equal(rc, -EINTR, "");
623
624 zassert_equal(cancel_events[0].state,
625 K_POLL_STATE_CANCELLED, "");
626
627 if (is_main_low_prio) {
628 /* If poller thread is lower priority than threads which
629 * generate poll events, it may get multiple poll events
630 * at once.
631 */
632 zassert_equal(cancel_events[1].state,
633 K_POLL_STATE_FIFO_DATA_AVAILABLE, "");
634 } else {
635 /* Otherwise, poller thread will be woken up on first
636 * event triggered.
637 */
638 zassert_equal(cancel_events[1].state,
639 K_POLL_STATE_NOT_READY, "");
640 }
641
642 k_thread_abort(tid);
643 }
644
ZTEST(poll_api_1cpu,test_poll_cancel_main_low_prio)645 ZTEST(poll_api_1cpu, test_poll_cancel_main_low_prio)
646 {
647 test_poll_cancel(true);
648 }
649
ZTEST(poll_api_1cpu,test_poll_cancel_main_high_prio)650 ZTEST(poll_api_1cpu, test_poll_cancel_main_high_prio)
651 {
652 test_poll_cancel(false);
653 }
654
655 /* verify multiple pollers */
656 static K_SEM_DEFINE(multi_sem, 0, 1);
657
multi_lowprio(void * p1,void * p2,void * p3)658 static void multi_lowprio(void *p1, void *p2, void *p3)
659 {
660 (void)p1; (void)p2; (void)p3;
661
662 struct k_poll_event event;
663 int rc;
664
665 k_poll_event_init(&event, K_POLL_TYPE_SEM_AVAILABLE,
666 K_POLL_MODE_NOTIFY_ONLY, &multi_sem);
667
668 (void)k_poll(&event, 1, K_FOREVER);
669 rc = k_sem_take(&multi_sem, K_FOREVER);
670 zassert_equal(rc, 0, "");
671 }
672
673 static K_SEM_DEFINE(multi_reply, 0, 1);
674
multi(void * p1,void * p2,void * p3)675 static void multi(void *p1, void *p2, void *p3)
676 {
677 (void)p1; (void)p2; (void)p3;
678
679 struct k_poll_event event;
680
681 k_poll_event_init(&event, K_POLL_TYPE_SEM_AVAILABLE,
682 K_POLL_MODE_NOTIFY_ONLY, &multi_sem);
683
684 (void)k_poll(&event, 1, K_FOREVER);
685 k_sem_take(&multi_sem, K_FOREVER);
686 k_sem_give(&multi_reply);
687 }
688
689 static K_SEM_DEFINE(multi_ready_sem, 1, 1);
690
691 /**
692 * @brief Test polling of multiple events
693 *
694 * @details
695 * - Test the multiple semaphore events as waitable events in poll.
696 *
697 * @ingroup kernel_poll_tests
698 *
699 * @see K_POLL_EVENT_INITIALIZER(), k_poll(), k_poll_event_init()
700 */
ZTEST(poll_api,test_poll_multi)701 ZTEST(poll_api, test_poll_multi)
702 {
703 int old_prio = k_thread_priority_get(k_current_get());
704 const int main_low_prio = 10;
705 int rc;
706
707 struct k_poll_event events[] = {
708 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
709 K_POLL_MODE_NOTIFY_ONLY,
710 &multi_sem),
711 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
712 K_POLL_MODE_NOTIFY_ONLY,
713 &multi_ready_sem),
714 };
715
716 k_thread_priority_set(k_current_get(), main_low_prio);
717
718 k_tid_t tid1 = k_thread_create(&test_thread, test_stack,
719 K_THREAD_STACK_SIZEOF(test_stack),
720 multi, 0, 0, 0, main_low_prio - 1,
721 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
722
723 /*
724 * create additional thread to add multiple(more than one)
725 * pending threads in events list to improve code coverage.
726 */
727 k_tid_t tid2 = k_thread_create(&test_loprio_thread, test_loprio_stack,
728 K_THREAD_STACK_SIZEOF(test_loprio_stack),
729 multi_lowprio, 0, 0, 0, main_low_prio + 1,
730 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
731
732 /* Allow lower priority thread to add poll event in the list */
733 k_sleep(K_MSEC(250));
734 rc = k_poll(events, ARRAY_SIZE(events), K_SECONDS(1));
735
736 zassert_equal(rc, 0, "");
737 zassert_equal(events[0].state, K_POLL_STATE_NOT_READY, "");
738 zassert_equal(events[1].state, K_POLL_STATE_SEM_AVAILABLE, "");
739
740 /*
741 * free polling threads, ensuring it awoken from k_poll()
742 * and got the sem
743 */
744 k_sem_give(&multi_sem);
745 k_sem_give(&multi_sem);
746 rc = k_sem_take(&multi_reply, K_SECONDS(1));
747
748 zassert_equal(rc, 0, "");
749
750 /* wait for polling threads to complete execution */
751 k_thread_priority_set(k_current_get(), old_prio);
752 k_sleep(K_MSEC(250));
753
754 k_thread_abort(tid1);
755 k_thread_abort(tid2);
756 }
757
758 static struct k_poll_signal signal;
759
threadstate(void * p1,void * p2,void * p3)760 static void threadstate(void *p1, void *p2, void *p3)
761 {
762 (void)p2; (void)p3;
763
764 k_sleep(K_MSEC(250));
765 /* Update polling thread state explicitly to improve code coverage */
766 k_thread_suspend(p1);
767 /* Enable polling thread by signalling */
768 k_poll_signal_raise(&signal, SIGNAL_RESULT);
769 k_thread_resume(p1);
770 }
771
772 /**
773 * @brief Test polling of events by manipulating polling thread state
774 *
775 * @details
776 * - manipulating thread state to consider case where no polling thread
777 * is available during event signalling.
778 * - defined a signal poll as waitable events in poll and
779 * verify the result after signal raised
780 *
781 * @ingroup kernel_poll_tests
782 *
783 * @see K_POLL_EVENT_INITIALIZER(), k_poll(), k_poll_signal_init(),
784 * k_poll_signal_check(), k_poll_signal_raise()
785 */
ZTEST(poll_api_1cpu,test_poll_threadstate)786 ZTEST(poll_api_1cpu, test_poll_threadstate)
787 {
788 unsigned int signaled;
789 const int main_low_prio = 10;
790 int result;
791
792 k_poll_signal_init(&signal);
793
794 struct k_poll_event event;
795
796 k_poll_event_init(&event, K_POLL_TYPE_SIGNAL,
797 K_POLL_MODE_NOTIFY_ONLY, &signal);
798
799 int old_prio = k_thread_priority_get(k_current_get());
800
801 k_thread_priority_set(k_current_get(), main_low_prio);
802 k_tid_t ztest_tid = k_current_get();
803
804 k_tid_t tid = k_thread_create(&test_thread, test_stack,
805 K_THREAD_STACK_SIZEOF(test_stack), threadstate,
806 ztest_tid, 0, 0, main_low_prio - 1, K_INHERIT_PERMS,
807 K_NO_WAIT);
808
809 /* wait for spawn thread to take action */
810 zassert_equal(k_poll(&event, 1, K_SECONDS(1)), 0, "");
811 zassert_equal(event.state, K_POLL_STATE_SIGNALED, "");
812 k_poll_signal_check(&signal, &signaled, &result);
813 zassert_not_equal(signaled, 0, "");
814 zassert_equal(result, SIGNAL_RESULT, "");
815
816 event.state = K_POLL_STATE_NOT_READY;
817 k_poll_signal_reset(&signal);
818 /* teardown */
819 k_thread_priority_set(k_current_get(), old_prio);
820
821 k_thread_abort(tid);
822 }
823
poll_test_grant_access(void)824 void poll_test_grant_access(void)
825 {
826 k_thread_access_grant(k_current_get(), &no_wait_sem, &no_wait_fifo,
827 &no_wait_signal, &wait_sem, &wait_fifo,
828 &cancel_fifo, &non_cancel_fifo,
829 &wait_signal, &test_thread, &test_signal,
830 &test_stack, &multi_sem, &multi_reply,
831 &no_wait_pipe, &wait_pipe);
832 }
833
834
high_prio_main(void * param1,void * param2,void * param3)835 static void high_prio_main(void *param1, void *param2, void *param3)
836 {
837 static struct k_poll_event poll_events[1];
838
839 /* Setup wake-up for message queue */
840 k_poll_event_init(&poll_events[0], K_POLL_TYPE_MSGQ_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY,
841 &msgq_high_prio_thread);
842 (void)k_poll(poll_events, 1, K_FOREVER);
843
844 zassert_equal(poll_events[0].state, K_POLL_STATE_MSGQ_DATA_AVAILABLE);
845 zassert_equal(wake_up_by_poll, true);
846 }
847
ZTEST(poll_api_1cpu,test_poll_msgq)848 ZTEST(poll_api_1cpu, test_poll_msgq)
849 {
850 int low_prio_thread_priority = 1;
851 int high_prio_thread_priority = -2;
852 unsigned int data_to_high_prio = 0x1234;
853
854 k_thread_priority_set(k_current_get(), low_prio_thread_priority);
855
856 /* Create high priority thread */
857 (void)k_thread_create(&high_prio_data, high_prio_stack_area,
858 K_THREAD_STACK_SIZEOF(high_prio_stack_area), high_prio_main, NULL,
859 NULL, NULL, high_prio_thread_priority, 0, K_NO_WAIT);
860 k_sleep(K_MSEC(1));
861 /* Send message to high-priority thread */
862 (void)k_msgq_put(&msgq_high_prio_thread, &data_to_high_prio, K_NO_WAIT);
863
864 /* low priority thread should not execute here before wake up high priority task */
865 wake_up_by_poll = false;
866 }
867
ZTEST(poll_api_1cpu,test_poll_zero_events)868 ZTEST(poll_api_1cpu, test_poll_zero_events)
869 {
870 struct k_poll_event event;
871
872 k_sem_init(&zero_events_sem, 1, 1);
873
874 k_poll_event_init(&event, K_POLL_TYPE_SEM_AVAILABLE,
875 K_POLL_MODE_NOTIFY_ONLY, &zero_events_sem);
876
877 zassert_equal(k_poll(&event, 0, K_MSEC(50)), -EAGAIN);
878 }
879