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