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