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