1 /*
2  * Copyright (c) 2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <wait_q.h>
9 
10 #define DELAY          K_MSEC(50)
11 #define SHORT_TIMEOUT  K_MSEC(100)
12 #define LONG_TIMEOUT   K_MSEC(1000)
13 
14 #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
15 
16 static struct k_thread treceiver;
17 static struct k_thread textra1;
18 static struct k_thread textra2;
19 
20 static K_THREAD_STACK_DEFINE(sreceiver, STACK_SIZE);
21 static K_THREAD_STACK_DEFINE(sextra1, STACK_SIZE);
22 static K_THREAD_STACK_DEFINE(sextra2, STACK_SIZE);
23 
24 static K_EVENT_DEFINE(test_event);
25 static K_EVENT_DEFINE(sync_event);
26 
27 static K_SEM_DEFINE(receiver_sem, 0, 1);
28 static K_SEM_DEFINE(sync_sem, 0, 1);
29 
30 volatile static uint32_t test_events;
31 
entry_extra1(void * p1,void * p2,void * p3)32 static void entry_extra1(void *p1, void *p2, void *p3)
33 {
34 	uint32_t  events;
35 
36 	events = k_event_wait_all(&sync_event, 0x33, true, K_FOREVER);
37 
38 	k_event_post(&test_event, events);
39 }
40 
entry_extra2(void * p1,void * p2,void * p3)41 static void entry_extra2(void *p1, void *p2, void *p3)
42 {
43 	uint32_t  events;
44 
45 	events = k_event_wait(&sync_event, 0x3300, true, K_FOREVER);
46 
47 	k_event_post(&test_event, events);
48 }
49 /**
50  * @ingroup kernel_event_tests
51  * @{
52  */
53 
54 /**
55  * Test the k_event_init() API.
56  *
57  * This is a white-box test to verify that the k_event_init() API initializes
58  * the fields of a k_event structure as expected.
59  */
ZTEST(events_api,test_k_event_init)60 ZTEST(events_api, test_k_event_init)
61 {
62 	static struct k_event  event;
63 	struct k_thread *thread;
64 
65 	k_event_init(&event);
66 
67 	/*
68 	 * The type of wait queue used by the event may vary depending upon
69 	 * which kernel features have been enabled. As such, the most flexible
70 	 * useful check is to verify that the waitq is empty.
71 	 */
72 
73 
74 	thread = z_waitq_head(&event.wait_q);
75 
76 	zassert_is_null(thread, NULL);
77 	zassert_true(event.events == 0);
78 }
79 
receive_existing_events(void)80 static void receive_existing_events(void)
81 {
82 	/*
83 	 * Sync point 1-1 : test_event contains events 0x1234.
84 	 * Test for events 0x2448 (no waiting)--expect an error
85 	 */
86 
87 	k_sem_take(&sync_sem, K_FOREVER);
88 	test_events = k_event_wait(&test_event, 0x2448, false, K_NO_WAIT);
89 	k_sem_give(&receiver_sem);
90 
91 	/*
92 	 * Sync point 1-2 : test_event still contains event 0x1234.
93 	 * Test for events 0x2448 (with waiting)--expect an error
94 	 */
95 
96 	k_sem_take(&sync_sem, K_FOREVER);
97 	test_events = k_event_wait(&test_event, 0x2448, false, SHORT_TIMEOUT);
98 	k_sem_give(&receiver_sem);
99 
100 	/*
101 	 * Sync point 1-3: test_event still contains event 0x1234.
102 	 * Test for events 0x1235 (no waiting)--expect an error
103 	 */
104 
105 	k_sem_take(&sync_sem, K_FOREVER);
106 	test_events = k_event_wait_all(&test_event, 0x1235, false, K_NO_WAIT);
107 	k_sem_give(&receiver_sem);
108 
109 	/*
110 	 * Sync point 1-4: test_event still contains event 0x1234.
111 	 * Test for events 0x1235 (no waiting)--expect an error
112 	 */
113 
114 	k_sem_take(&sync_sem, K_FOREVER);
115 	test_events = k_event_wait_all(&test_event, 0x1235, false, K_NO_WAIT);
116 	k_sem_give(&receiver_sem);
117 
118 	/*
119 	 * Sync point 1-5: test_event still contains event 0x1234.
120 	 * Test for events 0x0235. Expect 0x0234 to be returned.
121 	 */
122 
123 	k_sem_take(&sync_sem, K_FOREVER);
124 	test_events = k_event_wait(&test_event, 0x0235, false, K_NO_WAIT);
125 	k_sem_give(&receiver_sem);
126 
127 	/*
128 	 * Sync point 1-6: test_event still contains event 0x1234.
129 	 * Test for events 0x1234. Expect 0x1234 to be returned.
130 	 */
131 
132 	k_sem_take(&sync_sem, K_FOREVER);
133 	test_events = k_event_wait_all(&test_event, 0x1234, false, K_NO_WAIT);
134 	k_sem_give(&receiver_sem);
135 }
136 
reset_on_wait(void)137 static void reset_on_wait(void)
138 {
139 	/* Sync point 2-1 */
140 
141 	k_sem_take(&sync_sem, K_FOREVER);
142 	test_events = k_event_wait_all(&test_event, 0x1234, true,
143 				       SHORT_TIMEOUT);
144 	k_sem_give(&receiver_sem);
145 
146 	/* Sync point 2-2 */
147 
148 	k_sem_take(&sync_sem, K_FOREVER);
149 	test_events = k_event_wait(&test_event, 0x120000, true,
150 				   SHORT_TIMEOUT);
151 	k_sem_give(&receiver_sem);
152 
153 	/* Sync point 2-3 */
154 
155 	k_sem_take(&sync_sem, K_FOREVER);
156 	test_events = k_event_wait_all(&test_event, 0x248001, true,
157 				       SHORT_TIMEOUT);
158 	k_sem_give(&receiver_sem);
159 
160 	/* Sync point 2-4 */
161 
162 	k_sem_take(&sync_sem, K_FOREVER);
163 	test_events = k_event_wait(&test_event, 0x123458, true,
164 				   SHORT_TIMEOUT);
165 	k_sem_give(&receiver_sem);
166 }
167 
168 /**
169  * receiver helper task
170  */
171 
receiver(void * p1,void * p2,void * p3)172 static void receiver(void *p1, void *p2, void *p3)
173 {
174 	receive_existing_events();
175 
176 	reset_on_wait();
177 }
178 
179 /**
180  * Works with receive_existing_events() to test the waiting for events
181  * when some events have already been sent. No additional events are sent
182  * to the event object during this block of testing.
183  */
test_receive_existing_events(void)184 static void test_receive_existing_events(void)
185 {
186 	int  rv;
187 
188 	/*
189 	 * Sync point 1-1.
190 	 * K_NO_WAIT, k_event_wait(), no matches
191 	 */
192 
193 	k_sem_give(&sync_sem);
194 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
195 	zassert_true(rv == 0);
196 	zassert_true(test_events == 0);
197 
198 	/*
199 	 * Sync point 1-2.
200 	 * Short timeout, k_event_wait(), no expected matches
201 	 */
202 
203 	k_sem_give(&sync_sem);
204 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
205 	zassert_true(rv == 0);
206 	zassert_true(test_events == 0);
207 
208 	/*
209 	 * Sync point 1-3.
210 	 * K_NO_WAIT, k_event_wait_all(), incomplete match
211 	 */
212 
213 	k_sem_give(&sync_sem);
214 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
215 	zassert_true(rv == 0);
216 	zassert_true(test_events == 0);
217 
218 	/*
219 	 * Sync point 1-4.
220 	 * Short timeout, k_event_wait_all(), incomplete match
221 	 */
222 
223 	k_sem_give(&sync_sem);
224 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
225 	zassert_true(rv == 0);
226 	zassert_true(test_events == 0);
227 
228 	/*
229 	 * Sync point 1-5.
230 	 * Short timeout, k_event_wait_all(), incomplete match
231 	 */
232 
233 	k_sem_give(&sync_sem);
234 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
235 	zassert_true(rv == 0);
236 	zassert_true(test_events == 0x234);
237 
238 	/*
239 	 * Sync point 1-6.
240 	 * Short timeout, k_event_wait_all(), incomplete match
241 	 */
242 
243 	k_sem_give(&sync_sem);
244 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
245 	zassert_true(rv == 0);
246 	zassert_true(test_events == 0x1234);
247 }
248 
249 /**
250  * Works with reset_on_wait() to verify that the events stored in the
251  * event object are reset at the appropriate time.
252  */
253 
test_reset_on_wait(void)254 static void test_reset_on_wait(void)
255 {
256 	int  rv;
257 
258 	/*
259 	 * Sync point 2-1. Reset events before receive.
260 	 * Short timeout, k_event_wait_all(), incomplete match
261 	 */
262 
263 	k_sem_give(&sync_sem);
264 	k_sleep(DELAY);           /* Give receiver thread time to run */
265 	k_event_post(&test_event, 0x123);
266 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
267 	zassert_true(rv == 0);
268 	zassert_true(test_events == 0);
269 	zassert_true(test_event.events == 0x123);
270 
271 	/*
272 	 * Sync point 2-2. Reset events before receive.
273 	 * Short timeout, k_event_wait(), no matches
274 	 */
275 
276 	k_sem_give(&sync_sem);
277 	k_sleep(DELAY);
278 	k_event_post(&test_event, 0x248);
279 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
280 	zassert_true(rv == 0);
281 	zassert_true(test_events == 0);
282 	zassert_true(test_event.events == 0x248);
283 
284 	/*
285 	 * Sync point 2-3. Reset events before receive.
286 	 * Short timeout, k_event_wait_all(), complete match
287 	 */
288 
289 	k_sem_give(&sync_sem);
290 	k_sleep(DELAY);
291 	k_event_post(&test_event, 0x248021);
292 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
293 	zassert_true(rv == 0);
294 	zassert_true(test_events == 0x248001);
295 	zassert_true(test_event.events  == 0x248021);
296 
297 	/*
298 	 * Sync point 2-4. Reset events before receive.
299 	 * Short timeout, k_event_wait(), partial match
300 	 */
301 
302 	k_sem_give(&sync_sem);
303 	k_sleep(DELAY);
304 	k_event_post(&test_event, 0x123456);
305 	rv = k_sem_take(&receiver_sem, LONG_TIMEOUT);
306 	zassert_true(rv == 0);
307 	zassert_true(test_events == 0x123450);
308 	zassert_true(test_event.events  == 0x123456);
309 
310 	k_event_set(&test_event, 0x0);  /* Reset events */
311 	k_sem_give(&sync_sem);
312 }
313 
test_wake_multiple_threads(void)314 void test_wake_multiple_threads(void)
315 {
316 	uint32_t  events;
317 
318 	/*
319 	 * The extra threads are expected to be waiting on <sync_event>
320 	 * Wake them both up.
321 	 */
322 
323 	k_event_set(&sync_event, 0xfff);
324 
325 	/*
326 	 * The extra threads send back the events they received. Wait
327 	 * for all of them.
328 	 */
329 
330 	events = k_event_wait_all(&test_event, 0x333, false, SHORT_TIMEOUT);
331 
332 	zassert_true(events == 0x333);
333 }
334 
335 /**
336  * Test basic k_event_post() and k_event_set() APIs.
337  *
338  * Tests the basic k_event_post() and k_event_set() APIs. This does not
339  * involve waking or receiving events.
340  */
341 
ZTEST(events_api,test_event_deliver)342 ZTEST(events_api, test_event_deliver)
343 {
344 	static struct k_event  event;
345 	uint32_t  events;
346 	uint32_t  events_mask;
347 	uint32_t  previous;
348 
349 	k_event_init(&event);
350 
351 	zassert_equal(k_event_test(&event, ~0), 0);
352 
353 	/*
354 	 * Verify k_event_post()  and k_event_set() update the
355 	 * events stored in the event object as expected.
356 	 */
357 
358 	events = 0xAAAA;
359 	previous = k_event_post(&event, events);
360 	zassert_equal(previous, 0x0000);
361 	zassert_equal(k_event_test(&event, ~0), events);
362 
363 	events |= 0x55555ABC;
364 	previous = k_event_post(&event, events);
365 	zassert_equal(previous, events & 0xAAAA);
366 	zassert_equal(k_event_test(&event, ~0), events);
367 
368 	events = 0xAAAA0000;
369 	previous = k_event_set(&event, events);
370 	zassert_equal(previous, 0xAAAA | 0x55555ABC);
371 	zassert_equal(k_event_test(&event, ~0), events);
372 
373 	/*
374 	 * Verify k_event_set_masked() update the events
375 	 * stored in the event object as expected
376 	 */
377 	events = 0x33333333;
378 	(void)k_event_set(&event, events);
379 	zassert_equal(k_event_test(&event, ~0), events);
380 
381 	events_mask = 0x11111111;
382 	previous = k_event_set_masked(&event, 0, events_mask);
383 	zassert_equal(previous, 0x11111111);
384 	zassert_equal(k_event_test(&event, ~0), 0x22222222);
385 
386 	events_mask = 0x22222222;
387 	previous = k_event_set_masked(&event, 0, events_mask);
388 	zassert_equal(previous, 0x22222222);
389 	zassert_equal(k_event_test(&event, ~0), 0);
390 
391 	events = 0x22222222;
392 	events_mask = 0x22222222;
393 	previous = k_event_set_masked(&event, events, events_mask);
394 	zassert_equal(previous, 0x00000000);
395 	zassert_equal(k_event_test(&event, ~0), events);
396 
397 	events = 0x11111111;
398 	events_mask = 0x33333333;
399 	previous = k_event_set_masked(&event, events, events_mask);
400 	zassert_equal(previous, 0x22222222);
401 	zassert_equal(k_event_test(&event, ~0), events);
402 }
403 
404 /**
405  * Test delivery and reception of events.
406  *
407  * Testing both the delivery and reception of events involves the use of
408  * multiple threads and uses the following event related APIs:
409  *   k_event_post(), k_event_set(), k_event_wait() and k_event_wait_all().
410  */
411 
ZTEST(events_api,test_event_receive)412 ZTEST(events_api, test_event_receive)
413 {
414 
415 	/* Create helper threads */
416 
417 	k_event_set(&test_event, 0x1234);
418 
419 	(void) k_thread_create(&treceiver, sreceiver, STACK_SIZE,
420 			       receiver, NULL, NULL, NULL,
421 			       K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
422 
423 	(void) k_thread_create(&textra1, sextra1, STACK_SIZE,
424 			       entry_extra1, NULL, NULL, NULL,
425 			       K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
426 
427 	(void) k_thread_create(&textra2, sextra2, STACK_SIZE,
428 			       entry_extra2, NULL, NULL, NULL,
429 			       K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
430 
431 	test_receive_existing_events();
432 
433 	test_reset_on_wait();
434 
435 	test_wake_multiple_threads();
436 }
437 
ZTEST(events_api,test_k_event_wait_safe)438 ZTEST(events_api, test_k_event_wait_safe)
439 {
440 	uint32_t events;
441 
442 	k_event_set(&test_event, 0x73);
443 
444 	events = k_event_wait_safe(&test_event, 0x11, false, K_NO_WAIT);
445 	zexpect_equal(events, 0x11, "expected 0x11, got %x", events);
446 
447 	events = k_event_wait_safe(&test_event, 0x11, false, K_NO_WAIT);
448 	zexpect_equal(events, 0x0, "phantom events %x not removed from event object", events);
449 
450 	events = k_event_wait_safe(&test_event, 0x62, false, K_NO_WAIT);
451 	zexpect_equal(events, 0x62, "expected 0x62, got %x", events);
452 
453 	events = k_event_wait_safe(&test_event, -1, false, K_NO_WAIT);
454 	zexpect_equal(events, 0x0, "phantom events %x not removed from event object", events);
455 }
456 
ZTEST(events_api,test_k_event_wait_all_safe)457 ZTEST(events_api, test_k_event_wait_all_safe)
458 {
459 	uint32_t events;
460 
461 	k_event_set(&test_event, 0x73);
462 
463 	events = k_event_wait_all_safe(&test_event, 0x81, false, K_NO_WAIT);
464 	zexpect_equal(events, 0x0, "expected 0x0, got %x", events);
465 
466 	events = k_event_wait_all_safe(&test_event, 0x11, false, K_NO_WAIT);
467 	zexpect_equal(events, 0x11, "expected 0x11, got %x", events);
468 
469 	events = k_event_wait_all_safe(&test_event, 0x63, false, K_NO_WAIT);
470 	zexpect_equal(events, 0x0, "expected 0x0, got %x", events);
471 
472 	events = k_event_wait_all_safe(&test_event, 0x62, false, K_NO_WAIT);
473 	zexpect_equal(events, 0x62, "expected 0x62, got %x", events);
474 }
475 
476 /**
477  * @}
478  */
479