1 /*
2 * Copyright (c) 2016, 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/irq_offload.h>
9 #include <zephyr/ztest_error_hook.h>
10
11
12 /**
13 * @defgroup kernel_semaphore_tests Semaphores
14 * @ingroup all_tests
15 * @{
16 * @}
17 */
18
19 /* Macro declarations */
20 #define SEM_INIT_VAL (0U)
21 #define SEM_MAX_VAL (10U)
22 #define THREAD_TEST_PRIORITY 0
23
24 #define sem_give_from_isr(sema) irq_offload(isr_sem_give, (const void *)sema)
25 #define sem_take_from_isr(sema) irq_offload(isr_sem_take, (const void *)sema)
26
27 #define SEM_TIMEOUT (K_MSEC(100))
28 #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
29 #define TOTAL_THREADS_WAITING (5)
30
31 #define SEC2MS(s) ((s) * 1000)
32 #define QSEC2MS(s) ((s) * 250)
33
34 #define expect_k_sem_take(sem, timeout, exp, str) do { \
35 int _act = k_sem_take((sem), (timeout)); \
36 int _exp = (exp); \
37 zassert_equal(_act, _exp, (str), _act, _exp); \
38 } while (0)
39
40 #define expect_k_sem_init(sem, init, max, exp, str) do { \
41 int _act = k_sem_init((sem), (init), (max)); \
42 int _exp = (exp); \
43 zassert_equal(_act, _exp, (str), _act, _exp); \
44 } while (0)
45
46 #define expect_k_sem_count_get(sem, exp, str) do { \
47 unsigned int _act = k_sem_count_get(sem); \
48 unsigned int _exp = (exp); \
49 zassert_equal(_act, _exp, (str), _act, _exp); \
50 } while (0)
51
52 #define expect_k_sem_take_nomsg(sem, timeout, exp) \
53 expect_k_sem_take((sem), (timeout), (exp), "k_sem_take incorrect return value: %d != %d")
54 #define expect_k_sem_init_nomsg(sem, init, max, exp) \
55 expect_k_sem_init((sem), (init), (max), (exp), \
56 "k_sem_init incorrect return value: %d != %d")
57 #define expect_k_sem_count_get_nomsg(sem, exp) \
58 expect_k_sem_count_get((sem), (exp), "k_sem_count_get incorrect return value: %u != %u")
59
60 /* global variable for mutual exclusion test */
61 uint32_t critical_var;
62
63 struct timeout_info {
64 uint32_t timeout;
65 struct k_sem *sema;
66 };
67
68 /******************************************************************************/
69 /* Kobject declaration */
70 K_SEM_DEFINE(statically_defined_sem, SEM_INIT_VAL, SEM_MAX_VAL);
71 K_SEM_DEFINE(simple_sem, SEM_INIT_VAL, SEM_MAX_VAL);
72 K_SEM_DEFINE(low_prio_sem, SEM_INIT_VAL, SEM_MAX_VAL);
73 K_SEM_DEFINE(mid_prio_sem, SEM_INIT_VAL, SEM_MAX_VAL);
74 K_SEM_DEFINE(high_prio_long_sem, SEM_INIT_VAL, SEM_MAX_VAL);
75 K_SEM_DEFINE(high_prio_sem, SEM_INIT_VAL, SEM_MAX_VAL);
76 K_SEM_DEFINE(multiple_thread_sem, SEM_INIT_VAL, SEM_MAX_VAL);
77
78 K_THREAD_STACK_DEFINE(stack_1, STACK_SIZE);
79 K_THREAD_STACK_DEFINE(stack_2, STACK_SIZE);
80 K_THREAD_STACK_DEFINE(stack_3, STACK_SIZE);
81 K_THREAD_STACK_DEFINE(stack_4, STACK_SIZE);
82 K_THREAD_STACK_ARRAY_DEFINE(multiple_stack, TOTAL_THREADS_WAITING, STACK_SIZE);
83 K_PIPE_DEFINE(timeout_info_pipe,
84 sizeof(struct timeout_info) * TOTAL_THREADS_WAITING, 4);
85
86 struct k_thread sem_tid_1, sem_tid_2, sem_tid_3, sem_tid_4;
87 struct k_thread multiple_tid[TOTAL_THREADS_WAITING];
88
89 K_SEM_DEFINE(ksema, SEM_INIT_VAL, SEM_MAX_VAL);
90 struct k_sem msg_sema, mut_sem;
91 static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
92 struct k_thread tdata;
93
94 /******************************************************************************/
95 /* Helper functions */
96
sem_give_task(void * p1,void * p2,void * p3)97 void sem_give_task(void *p1, void *p2, void *p3)
98 {
99 k_sem_give((struct k_sem *)p1);
100 }
101
sem_reset_take_task(void * p1,void * p2,void * p3)102 void sem_reset_take_task(void *p1, void *p2, void *p3)
103 {
104 k_sem_reset((struct k_sem *)p1);
105 zassert_false(k_sem_take((struct k_sem *)p1, K_FOREVER));
106 }
107
isr_sem_give(const void * semaphore)108 void isr_sem_give(const void *semaphore)
109 {
110 k_sem_give((struct k_sem *)semaphore);
111 }
112
tsema_thread_thread(struct k_sem * psem)113 static void tsema_thread_thread(struct k_sem *psem)
114 {
115 /**TESTPOINT: thread-thread sync via sema*/
116 k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
117 sem_give_task, psem, NULL, NULL,
118 K_PRIO_PREEMPT(0),
119 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
120
121 expect_k_sem_take_nomsg(psem, K_FOREVER, 0);
122
123 /*clean the spawn thread avoid side effect in next TC*/
124 k_thread_join(tid, K_FOREVER);
125 }
126
tsema_thread_isr(struct k_sem * psem)127 static void tsema_thread_isr(struct k_sem *psem)
128 {
129 /**TESTPOINT: thread-isr sync via sema*/
130 irq_offload(isr_sem_give, (const void *)psem);
131
132 expect_k_sem_take_nomsg(psem, K_FOREVER, 0);
133 }
134
135
isr_sem_take(const void * semaphore)136 void isr_sem_take(const void *semaphore)
137 {
138 int ret = k_sem_take((struct k_sem *)semaphore, K_NO_WAIT);
139
140 if (ret != 0 && ret != -EBUSY) {
141 zassert_true(false, "incorrect k_sem_take return: %d", ret);
142 }
143 }
144
145
146
sem_take_timeout_forever_helper(void * p1,void * p2,void * p3)147 void sem_take_timeout_forever_helper(void *p1, void *p2, void *p3)
148 {
149 k_sleep(K_MSEC(100));
150 k_sem_give(&simple_sem);
151 }
152
sem_take_timeout_isr_helper(void * p1,void * p2,void * p3)153 void sem_take_timeout_isr_helper(void *p1, void *p2, void *p3)
154 {
155 sem_give_from_isr(&simple_sem);
156 }
157
sem_take_multiple_low_prio_helper(void * p1,void * p2,void * p3)158 void sem_take_multiple_low_prio_helper(void *p1, void *p2, void *p3)
159 {
160 expect_k_sem_take_nomsg(&low_prio_sem, K_FOREVER, 0);
161 expect_k_sem_take_nomsg(&multiple_thread_sem, K_FOREVER, 0);
162
163 k_sem_give(&low_prio_sem);
164 }
165
sem_take_multiple_mid_prio_helper(void * p1,void * p2,void * p3)166 void sem_take_multiple_mid_prio_helper(void *p1, void *p2, void *p3)
167 {
168 expect_k_sem_take_nomsg(&mid_prio_sem, K_FOREVER, 0);
169 expect_k_sem_take_nomsg(&multiple_thread_sem, K_FOREVER, 0);
170
171 k_sem_give(&mid_prio_sem);
172 }
173
sem_take_multiple_high_prio_helper(void * p1,void * p2,void * p3)174 void sem_take_multiple_high_prio_helper(void *p1, void *p2, void *p3)
175 {
176
177 expect_k_sem_take_nomsg(&high_prio_sem, K_FOREVER, 0);
178 expect_k_sem_take_nomsg(&multiple_thread_sem, K_FOREVER, 0);
179
180 k_sem_give(&high_prio_sem);
181 }
182
183 /* First function for mutual exclusion test */
sem_queue_mutual_exclusion1(void * p1,void * p2,void * p3)184 void sem_queue_mutual_exclusion1(void *p1, void *p2, void *p3)
185 {
186 for (int i = 0; i < 1000; i++) {
187 expect_k_sem_take_nomsg(&mut_sem, K_FOREVER, 0);
188
189 /* in that function critical section makes critical var +1 */
190 uint32_t tmp = critical_var;
191 critical_var += 1;
192
193 /* Check that common value was not changed by another thread,
194 * when semaphore is taken by current thread, and no other
195 * thread can enter the critical section
196 */
197 zassert_true(critical_var == tmp + 1);
198 k_sem_give(&mut_sem);
199 }
200 }
201
202 /* Second function for mutual exclusion test */
sem_queue_mutual_exclusion2(void * p1,void * p2,void * p3)203 void sem_queue_mutual_exclusion2(void *p1, void *p2, void *p3)
204 {
205 for (int i = 0; i < 1000; i++) {
206 expect_k_sem_take_nomsg(&mut_sem, K_FOREVER, 0);
207
208 /* in that function critical section makes critical var 0 */
209 uint32_t tmp = critical_var;
210 critical_var -= 1;
211
212 /* Check that common value was not changed by another thread,
213 * when semaphore is taken by current thread, and no other
214 * thread can enter the critical section
215 */
216 zassert_true(critical_var == tmp - 1);
217 k_sem_give(&mut_sem);
218 }
219 }
220
sem_take_multiple_high_prio_long_helper(void * p1,void * p2,void * p3)221 void sem_take_multiple_high_prio_long_helper(void *p1, void *p2, void *p3)
222 {
223 expect_k_sem_take_nomsg(&high_prio_long_sem, K_FOREVER, 0);
224 expect_k_sem_take_nomsg(&multiple_thread_sem, K_FOREVER, 0);
225
226 k_sem_give(&high_prio_long_sem);
227 }
228
229 /**
230 * @ingroup kernel_semaphore_tests
231 * @{
232 */
233
234
235 /**
236 * @brief Test semaphore defined at compile time
237 * @details
238 * - Get the semaphore count.
239 * - Verify the semaphore count equals to initialized value.
240 * @ingroup kernel_semaphore_tests
241 * @see k_sem_count_get()
242 */
ZTEST_USER(semaphore,test_k_sem_define)243 ZTEST_USER(semaphore, test_k_sem_define)
244 {
245 /* verify the semaphore count equals to initialized value */
246 expect_k_sem_count_get(&statically_defined_sem, SEM_INIT_VAL,
247 "semaphore initialized failed at compile time"
248 "- got %u, expected %u");
249 }
250
251 /**
252 * @brief Test synchronization of threads with semaphore
253 * @see k_sem_init(), #K_SEM_DEFINE(x)
254 */
ZTEST_USER(semaphore,test_sem_thread2thread)255 ZTEST_USER(semaphore, test_sem_thread2thread)
256 {
257 /**TESTPOINT: test k_sem_init sema*/
258 expect_k_sem_init_nomsg(&msg_sema, SEM_INIT_VAL, SEM_MAX_VAL, 0);
259
260 tsema_thread_thread(&msg_sema);
261
262 /**TESTPOINT: test K_SEM_DEFINE sema*/
263 tsema_thread_thread(&ksema);
264 }
265
266 /**
267 * @brief Test synchronization between thread and irq
268 * @see k_sem_init(), #K_SEM_DEFINE(x)
269 */
ZTEST(semaphore,test_sem_thread2isr)270 ZTEST(semaphore, test_sem_thread2isr)
271 {
272 /**TESTPOINT: test k_sem_init sema*/
273 expect_k_sem_init_nomsg(&msg_sema, SEM_INIT_VAL, SEM_MAX_VAL, 0);
274
275 tsema_thread_isr(&msg_sema);
276
277 /**TESTPOINT: test K_SEM_DEFINE sema*/
278 tsema_thread_isr(&ksema);
279 }
280
281 /**
282 * @brief Test semaphore initialization at runtime
283 * @details
284 * - Initialize a semaphore with valid count and max limit.
285 * - Initialize a semaphore with invalid max limit.
286 * - Initialize a semaphore with invalid count.
287 * @ingroup kernel_semaphore_tests
288 */
ZTEST_USER(semaphore,test_k_sem_init)289 ZTEST_USER(semaphore, test_k_sem_init)
290 {
291 /* initialize a semaphore with valid count and max limit */
292 expect_k_sem_init_nomsg(&msg_sema, SEM_INIT_VAL, SEM_MAX_VAL, 0);
293
294 k_sem_reset(&msg_sema);
295
296 /* initialize a semaphore with invalid max limit */
297 expect_k_sem_init_nomsg(&msg_sema, SEM_INIT_VAL, 0, -EINVAL);
298
299 /* initialize a semaphore with invalid count */
300 expect_k_sem_init_nomsg(&msg_sema, SEM_MAX_VAL + 1, SEM_MAX_VAL, -EINVAL);
301 }
302
303
304 /**
305 * @brief Test k_sem_reset() API
306 * @see k_sem_reset()
307 */
ZTEST_USER(semaphore,test_sem_reset)308 ZTEST_USER(semaphore, test_sem_reset)
309 {
310 expect_k_sem_init_nomsg(&msg_sema, SEM_INIT_VAL, SEM_MAX_VAL, 0);
311 expect_k_sem_count_get_nomsg(&msg_sema, 0);
312
313 k_sem_give(&msg_sema);
314 expect_k_sem_count_get_nomsg(&msg_sema, 1);
315 k_sem_reset(&msg_sema);
316 expect_k_sem_count_get_nomsg(&msg_sema, 0);
317
318 /**TESTPOINT: semaphore take return -EBUSY*/
319 expect_k_sem_take_nomsg(&msg_sema, K_NO_WAIT, -EBUSY);
320 expect_k_sem_count_get_nomsg(&msg_sema, 0);
321
322 /**TESTPOINT: semaphore take return -EAGAIN*/
323 expect_k_sem_take_nomsg(&msg_sema, SEM_TIMEOUT, -EAGAIN);
324 expect_k_sem_count_get_nomsg(&msg_sema, 0);
325
326 k_sem_give(&msg_sema);
327 expect_k_sem_count_get_nomsg(&msg_sema, 1);
328
329 expect_k_sem_take_nomsg(&msg_sema, K_FOREVER, 0);
330 expect_k_sem_count_get_nomsg(&msg_sema, 0);
331 }
332
ZTEST_USER(semaphore,test_sem_reset_waiting)333 ZTEST_USER(semaphore, test_sem_reset_waiting)
334 {
335 int32_t ret_value;
336
337 k_sem_reset(&simple_sem);
338
339 /* create a new thread. It will reset the semaphore in 1ms
340 * then wait for us.
341 */
342 k_tid_t tid = k_thread_create(&sem_tid_1, stack_1, STACK_SIZE,
343 sem_reset_take_task, &simple_sem, NULL, NULL,
344 K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS,
345 K_MSEC(1));
346
347 /* Take semaphore and wait for the abort. */
348 ret_value = k_sem_take(&simple_sem, K_FOREVER);
349 zassert_true(ret_value == -EAGAIN, "k_sem_take not aborted: %d",
350 ret_value);
351
352 /* ensure the semaphore is still functional after. */
353 k_sem_give(&simple_sem);
354
355 k_thread_join(tid, K_FOREVER);
356 }
357
358 /**
359 * @brief Test k_sem_count_get() API
360 * @see k_sem_count_get()
361 */
ZTEST_USER(semaphore,test_sem_count_get)362 ZTEST_USER(semaphore, test_sem_count_get)
363 {
364 expect_k_sem_init_nomsg(&msg_sema, SEM_INIT_VAL, SEM_MAX_VAL, 0);
365
366 /**TESTPOINT: semaphore count get upon init*/
367 expect_k_sem_count_get_nomsg(&msg_sema, SEM_INIT_VAL);
368 k_sem_give(&msg_sema);
369 /**TESTPOINT: sem count get after give*/
370 expect_k_sem_count_get_nomsg(&msg_sema, SEM_INIT_VAL + 1);
371 expect_k_sem_take_nomsg(&msg_sema, K_FOREVER, 0);
372 /**TESTPOINT: sem count get after take*/
373 for (int i = 0; i < SEM_MAX_VAL; i++) {
374 expect_k_sem_count_get_nomsg(&msg_sema, SEM_INIT_VAL + i);
375 k_sem_give(&msg_sema);
376 }
377 /**TESTPOINT: semaphore give above limit*/
378 k_sem_give(&msg_sema);
379 expect_k_sem_count_get_nomsg(&msg_sema, SEM_MAX_VAL);
380 }
381
382
383 /**
384 * @brief Test whether a semaphore can be given by an ISR
385 * @details
386 * - Reset an initialized semaphore's count to zero
387 * - Create a loop, in each loop, do follow steps
388 * - Give the semaphore from an ISR
389 * - Get the semaphore's count
390 * - Verify whether the semaphore's count as expected
391 * @ingroup kernel_semaphore_tests
392 * @see k_sem_give()
393 */
ZTEST(semaphore,test_sem_give_from_isr)394 ZTEST(semaphore, test_sem_give_from_isr)
395 {
396 /*
397 * Signal the semaphore several times from an ISR. After each signal,
398 * check the signal count.
399 */
400
401 k_sem_reset(&simple_sem);
402 expect_k_sem_count_get_nomsg(&simple_sem, 0);
403
404 for (int i = 0; i < 5; i++) {
405 sem_give_from_isr(&simple_sem);
406
407 expect_k_sem_count_get_nomsg(&simple_sem, i + 1);
408 }
409 }
410
411 /**
412 * @brief Test semaphore count when given by thread
413 * @details
414 * - Reset an initialized semaphore's count to zero
415 * - Create a loop, in each loop, do follow steps
416 * - Give the semaphore from a thread
417 * - Get the semaphore's count
418 * - Verify whether the semaphore's count as expected
419 * @ingroup kernel_semaphore_tests
420 * @see k_sem_give()
421 */
ZTEST_USER(semaphore,test_sem_give_from_thread)422 ZTEST_USER(semaphore, test_sem_give_from_thread)
423 {
424 /*
425 * Signal the semaphore several times from a task. After each signal,
426 * check the signal count.
427 */
428
429 k_sem_reset(&simple_sem);
430 expect_k_sem_count_get_nomsg(&simple_sem, 0);
431
432 for (int i = 0; i < 5; i++) {
433 k_sem_give(&simple_sem);
434
435 expect_k_sem_count_get_nomsg(&simple_sem, i + 1);
436 }
437
438 }
439
440 /**
441 * @brief Test if k_sem_take() decreases semaphore count
442 * @see k_sem_take()
443 */
ZTEST_USER(semaphore,test_sem_take_no_wait)444 ZTEST_USER(semaphore, test_sem_take_no_wait)
445 {
446 /*
447 * Test the semaphore without wait. Check the signal count after each
448 * attempt (it should be decrementing by 1 each time).
449 */
450
451 k_sem_reset(&simple_sem);
452 for (int i = 0; i < 5; i++) {
453 k_sem_give(&simple_sem);
454 }
455
456 for (int i = 4; i >= 0; i--) {
457 expect_k_sem_take_nomsg(&simple_sem, K_NO_WAIT, 0);
458 expect_k_sem_count_get_nomsg(&simple_sem, i);
459 }
460 }
461
462 /**
463 * @brief Test k_sem_take() when there is no semaphore to take
464 * @see k_sem_take()
465 */
ZTEST_USER(semaphore,test_sem_take_no_wait_fails)466 ZTEST_USER(semaphore, test_sem_take_no_wait_fails)
467 {
468 /*
469 * Test the semaphore without wait. Check the signal count after each
470 * attempt (it should be always zero).
471 */
472
473 k_sem_reset(&simple_sem);
474
475 for (int i = 4; i >= 0; i--) {
476 expect_k_sem_take_nomsg(&simple_sem, K_NO_WAIT, -EBUSY);
477 expect_k_sem_count_get_nomsg(&simple_sem, 0);
478 }
479
480 }
481
482 /**
483 * @brief Test a semaphore take operation with an unavailable semaphore
484 * @details
485 * - Reset the semaphore's count to zero, let it unavailable.
486 * - Take an unavailable semaphore and wait it until timeout.
487 * @ingroup kernel_semaphore_tests
488 * @see k_sem_take()
489 */
ZTEST_USER(semaphore,test_sem_take_timeout_fails)490 ZTEST_USER(semaphore, test_sem_take_timeout_fails)
491 {
492 /*
493 * Test the semaphore with timeout without a k_sem_give.
494 */
495 k_sem_reset(&simple_sem);
496 expect_k_sem_count_get_nomsg(&simple_sem, 0);
497
498 /* take an unavailable semaphore and wait it until timeout */
499 for (int i = 4; i >= 0; i--) {
500 expect_k_sem_take_nomsg(&simple_sem, SEM_TIMEOUT, -EAGAIN);
501 }
502 }
503
504 /**
505 * @brief Test the semaphore take operation with specified timeout
506 * @details
507 * - Create a new thread, it will give semaphore.
508 * - Reset the semaphore's count to zero.
509 * - Take semaphore and wait it given by other threads in specified timeout.
510 * @ingroup kernel_semaphore_tests
511 * @see k_sem_take()
512 */
ZTEST_USER(semaphore,test_sem_take_timeout)513 ZTEST_USER(semaphore, test_sem_take_timeout)
514 {
515 /*
516 * Signal the semaphore upon which the other thread is waiting.
517 * The thread (which is at a lower priority) will cause simple_sem
518 * to be signalled, thus waking up this task.
519 */
520
521 /* create a new thread, it will give semaphore */
522 k_thread_create(&sem_tid_1, stack_1, STACK_SIZE,
523 sem_give_task, &simple_sem, NULL, NULL,
524 K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS,
525 K_FOREVER);
526
527 k_sem_reset(&simple_sem);
528
529 expect_k_sem_count_get_nomsg(&simple_sem, 0);
530
531 k_thread_start(&sem_tid_1);
532 /* Take semaphore and wait it given by other threads
533 * in specified timeout
534 */
535 expect_k_sem_take_nomsg(&simple_sem, SEM_TIMEOUT, 0);
536 k_thread_join(&sem_tid_1, K_FOREVER);
537 }
538
539 /**
540 * @brief Test the semaphore take operation with forever wait
541 * @details
542 * - Create a new thread, it will give semaphore.
543 * - Reset the semaphore's count to zero.
544 * - Take semaphore, wait it given by other thread forever until it's available.
545 * @ingroup kernel_semaphore_tests
546 * @see k_sem_take()
547 */
ZTEST_USER(semaphore,test_sem_take_timeout_forever)548 ZTEST_USER(semaphore, test_sem_take_timeout_forever)
549 {
550 /*
551 * Signal the semaphore upon which the another thread is waiting. The
552 * thread (which is at a lower priority) will cause simple_sem
553 * to be signalled, thus waking this task.
554 */
555
556 k_thread_create(&sem_tid_1, stack_1, STACK_SIZE,
557 sem_take_timeout_forever_helper, NULL, NULL, NULL,
558 K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS,
559 K_NO_WAIT);
560
561 k_sem_reset(&simple_sem);
562
563 expect_k_sem_count_get_nomsg(&simple_sem, 0);
564
565 /* Take semaphore and wait it given by
566 * other threads forever until it's available
567 */
568 expect_k_sem_take_nomsg(&simple_sem, K_FOREVER, 0);
569 k_thread_join(&sem_tid_1, K_FOREVER);
570 }
571
572 /**
573 * @brief Test k_sem_take() with timeout in ISR context
574 * @see k_sem_take()
575 */
ZTEST(semaphore_1cpu,test_sem_take_timeout_isr)576 ZTEST(semaphore_1cpu, test_sem_take_timeout_isr)
577 {
578 /*
579 * Signal the semaphore upon which the another thread is waiting. The
580 * thread (which is at a lower priority) will cause simple_sem
581 * to be signalled, thus waking this task.
582 */
583
584 k_thread_create(&sem_tid_1, stack_1, STACK_SIZE,
585 sem_take_timeout_isr_helper, NULL, NULL, NULL,
586 K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
587
588 k_sem_reset(&simple_sem);
589
590 expect_k_sem_take_nomsg(&simple_sem, SEM_TIMEOUT, 0);
591
592 k_thread_join(&sem_tid_1, K_FOREVER);
593 }
594
595 /**
596 * @brief Test semaphore take operation by multiple threads
597 * @ingroup kernel_semaphore_tests
598 * @see k_sem_take()
599 */
ZTEST_USER(semaphore,test_sem_take_multiple)600 ZTEST_USER(semaphore, test_sem_take_multiple)
601 {
602 k_sem_reset(&multiple_thread_sem);
603 k_sem_reset(&high_prio_long_sem);
604 k_sem_reset(&mid_prio_sem);
605 k_sem_reset(&low_prio_sem);
606 k_sem_reset(&high_prio_sem);
607 expect_k_sem_count_get_nomsg(&multiple_thread_sem, 0);
608 expect_k_sem_count_get_nomsg(&high_prio_long_sem, 0);
609 expect_k_sem_count_get_nomsg(&mid_prio_sem, 0);
610 expect_k_sem_count_get_nomsg(&low_prio_sem, 0);
611 expect_k_sem_count_get_nomsg(&high_prio_sem, 0);
612 /*
613 * Signal the semaphore upon which the another thread is waiting.
614 * The thread (which is at a lower priority) will cause simple_sem
615 * to be signalled, thus waking this task.
616 */
617
618 k_thread_create(&sem_tid_1, stack_1, STACK_SIZE,
619 sem_take_multiple_low_prio_helper,
620 NULL, NULL, NULL,
621 K_PRIO_PREEMPT(3), K_USER | K_INHERIT_PERMS,
622 K_NO_WAIT);
623
624 k_thread_create(&sem_tid_2, stack_2, STACK_SIZE,
625 sem_take_multiple_mid_prio_helper,
626 NULL, NULL, NULL,
627 K_PRIO_PREEMPT(2), K_USER | K_INHERIT_PERMS,
628 K_NO_WAIT);
629
630 k_thread_create(&sem_tid_3, stack_3, STACK_SIZE,
631 sem_take_multiple_high_prio_long_helper,
632 NULL, NULL, NULL,
633 K_PRIO_PREEMPT(1), K_USER | K_INHERIT_PERMS,
634 K_NO_WAIT);
635
636 /* Create another high priority thread, the same priority with sem_tid_3
637 * sem_tid_3 and sem_tid_4 are the same highest priority,
638 * but the waiting time of sem_tid_3 is longer than sem_tid_4.
639 * If some threads are the same priority, the sem given operation
640 * should be decided according to waiting time.
641 * That thread is necessary to test if a sem is available,
642 * it should be given to the highest priority and longest waiting thread
643 */
644 k_thread_create(&sem_tid_4, stack_4, STACK_SIZE,
645 sem_take_multiple_high_prio_helper, NULL, NULL,
646 NULL, K_PRIO_PREEMPT(1), K_USER | K_INHERIT_PERMS,
647 K_NO_WAIT);
648
649 /* time for those 4 threads to complete */
650 k_sleep(K_MSEC(20));
651
652 /* Let these threads proceed to take the multiple_sem
653 * make thread 1 to 3 waiting on multiple_thread_sem
654 */
655 k_sem_give(&high_prio_long_sem);
656 k_sem_give(&mid_prio_sem);
657 k_sem_give(&low_prio_sem);
658
659 /* Delay 100ms to make sem_tid_4 waiting on multiple_thread_sem,
660 * then waiting time of sem_tid_4 is shorter than sem_tid_3
661 */
662 k_sleep(K_MSEC(100));
663 k_sem_give(&high_prio_sem);
664
665 k_sleep(K_MSEC(20));
666
667 /* enable the high prio and long waiting thread sem_tid_3 to run */
668 k_sem_give(&multiple_thread_sem);
669 k_sleep(K_MSEC(200));
670
671 /* check which threads completed */
672 expect_k_sem_count_get(&high_prio_long_sem, 1,
673 "High priority and long waiting thread "
674 "don't get the sem: %u != %u");
675
676 expect_k_sem_count_get(&high_prio_sem, 0U,
677 "High priority thread shouldn't get the sem: %u != %u");
678
679 expect_k_sem_count_get(&mid_prio_sem, 0U,
680 "Medium priority threads shouldn't have executed: %u != %u");
681
682 expect_k_sem_count_get(&low_prio_sem, 0U,
683 "Low priority threads shouldn't have executed: %u != %u");
684
685 /* enable the high prio thread sem_tid_4 to run */
686 k_sem_give(&multiple_thread_sem);
687 k_sleep(K_MSEC(200));
688
689 /* check which threads completed */
690 expect_k_sem_count_get(&high_prio_long_sem, 1U,
691 "High priority and long waiting thread executed again: %u != %u");
692
693 expect_k_sem_count_get(&high_prio_sem, 1U,
694 "Higher priority thread did not get the sem: %u != %u");
695
696 expect_k_sem_count_get(&mid_prio_sem, 0U,
697 "Medium priority thread shouldn't get the sem: %u != %u");
698
699 expect_k_sem_count_get(&low_prio_sem, 0U,
700 "Low priority thread shouldn't get the sem: %u != %u");
701
702 /* enable the mid prio thread sem_tid_2 to run */
703 k_sem_give(&multiple_thread_sem);
704 k_sleep(K_MSEC(200));
705
706 /* check which threads completed */
707 expect_k_sem_count_get(&high_prio_long_sem, 1U,
708 "High priority and long waiting thread executed again: %u != %u");
709
710 expect_k_sem_count_get(&high_prio_sem, 1U,
711 "High priority thread executed again: %u != %u");
712
713 expect_k_sem_count_get(&mid_prio_sem, 1U,
714 "Medium priority thread did not get the sem: %u != %u");
715
716 expect_k_sem_count_get(&low_prio_sem, 0U,
717 "Low priority thread did not get the sem: %u != %u");
718
719 /* enable the low prio thread(thread_1) to run */
720 k_sem_give(&multiple_thread_sem);
721 k_sleep(K_MSEC(200));
722
723 /* check the thread completed */
724 expect_k_sem_count_get(&high_prio_long_sem, 1U,
725 "High priority and long waiting thread executed again: %u != %u");
726
727 expect_k_sem_count_get(&high_prio_sem, 1U,
728 "High priority thread executed again: %u != %u");
729
730 expect_k_sem_count_get(&mid_prio_sem, 1U,
731 "Mid priority thread executed again: %u != %u");
732
733 expect_k_sem_count_get(&low_prio_sem, 1U,
734 "Low priority thread did not get the sem: %u != %u");
735
736 k_thread_join(&sem_tid_1, K_FOREVER);
737 k_thread_join(&sem_tid_2, K_FOREVER);
738 k_thread_join(&sem_tid_3, K_FOREVER);
739 k_thread_join(&sem_tid_4, K_FOREVER);
740 }
741
742 /**
743 * @brief Test the max value a semaphore can be given and taken
744 * @details
745 * - Reset an initialized semaphore's count to zero.
746 * - Give the semaphore by a thread and verify the semaphore's count is
747 * as expected.
748 * - Verify the max count a semaphore can reach.
749 * - Take the semaphore by a thread and verify the semaphore's count is
750 * as expected.
751 * - Verify the max times a semaphore can be taken.
752 * @ingroup kernel_semaphore_tests
753 * @see k_sem_count_get(), k_sem_give()
754 */
ZTEST_USER(semaphore,test_k_sem_correct_count_limit)755 ZTEST_USER(semaphore, test_k_sem_correct_count_limit)
756 {
757
758 /* reset an initialized semaphore's count to zero */
759 k_sem_reset(&simple_sem);
760 expect_k_sem_count_get(&simple_sem, 0U, "k_sem_reset failed: %u != %u");
761
762 /* Give the semaphore by a thread and verify the semaphore's
763 * count is as expected
764 */
765 for (int i = 1; i <= SEM_MAX_VAL; i++) {
766 k_sem_give(&simple_sem);
767 expect_k_sem_count_get_nomsg(&simple_sem, i);
768 }
769
770 /* Verify the max count a semaphore can reach
771 * continue to run k_sem_give,
772 * the count of simple_sem will not increase anymore
773 */
774 for (int i = 0; i < 5; i++) {
775 k_sem_give(&simple_sem);
776 expect_k_sem_count_get_nomsg(&simple_sem, SEM_MAX_VAL);
777 }
778
779 /* Take the semaphore by a thread and verify the semaphore's
780 * count is as expected
781 */
782 for (int i = SEM_MAX_VAL - 1; i >= 0; i--) {
783 expect_k_sem_take_nomsg(&simple_sem, K_NO_WAIT, 0);
784 expect_k_sem_count_get_nomsg(&simple_sem, i);
785 }
786
787 /* Verify the max times a semaphore can be taken
788 * continue to run k_sem_take, simple_sem can not be taken and
789 * it's count will be zero
790 */
791 for (int i = 0; i < 5; i++) {
792 expect_k_sem_take_nomsg(&simple_sem, K_NO_WAIT, -EBUSY);
793
794 expect_k_sem_count_get_nomsg(&simple_sem, 0U);
795 }
796 }
797
798 /**
799 * @brief Test semaphore give and take and its count from ISR
800 * @see k_sem_give()
801 */
ZTEST(semaphore,test_sem_give_take_from_isr)802 ZTEST(semaphore, test_sem_give_take_from_isr)
803 {
804 k_sem_reset(&simple_sem);
805 expect_k_sem_count_get_nomsg(&simple_sem, 0U);
806
807 /* give semaphore from an isr and do a check for the count */
808 for (int i = 0; i < SEM_MAX_VAL; i++) {
809 sem_give_from_isr(&simple_sem);
810 expect_k_sem_count_get_nomsg(&simple_sem, i + 1);
811 }
812
813 /* take semaphore from an isr and do a check for the count */
814 for (int i = SEM_MAX_VAL; i > 0; i--) {
815 sem_take_from_isr(&simple_sem);
816
817 expect_k_sem_count_get_nomsg(&simple_sem, i - 1);
818 }
819 }
820
821 /**
822 * @}
823 */
824
sem_multiple_threads_wait_helper(void * p1,void * p2,void * p3)825 void sem_multiple_threads_wait_helper(void *p1, void *p2, void *p3)
826 {
827 /* get blocked until the test thread gives the semaphore */
828 expect_k_sem_take_nomsg(&multiple_thread_sem, K_FOREVER, 0);
829
830 /* inform the test thread that this thread has got multiple_thread_sem*/
831 k_sem_give(&simple_sem);
832 }
833
834
835 /**
836 * @brief Test multiple semaphore take and give with wait
837 * @ingroup kernel_semaphore_tests
838 * @see k_sem_take(), k_sem_give()
839 */
ZTEST(semaphore,test_sem_multiple_threads_wait)840 ZTEST(semaphore, test_sem_multiple_threads_wait)
841 {
842 k_sem_reset(&simple_sem);
843 k_sem_reset(&multiple_thread_sem);
844
845 /* Verify a wait q that has been emptied / reset
846 * correctly by running twice.
847 */
848 for (int repeat_count = 0; repeat_count < 2; repeat_count++) {
849 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
850 k_thread_create(&multiple_tid[i],
851 multiple_stack[i], STACK_SIZE,
852 sem_multiple_threads_wait_helper,
853 NULL, NULL, NULL,
854 K_PRIO_PREEMPT(1),
855 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
856 }
857
858 /* giving time for the other threads to execute */
859 k_sleep(K_MSEC(500));
860
861 /* give the semaphores */
862 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
863 k_sem_give(&multiple_thread_sem);
864 }
865
866 /* giving time for the other threads to execute */
867 k_sleep(K_MSEC(500));
868
869 /* check if all the threads are done. */
870 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
871 expect_k_sem_take(&simple_sem, K_FOREVER, 0,
872 "Some of the threads did not get multiple_thread_sem: %d != %d");
873 }
874
875 expect_k_sem_count_get_nomsg(&simple_sem, 0U);
876 expect_k_sem_count_get_nomsg(&multiple_thread_sem, 0U);
877
878 }
879 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
880 k_thread_join(&multiple_tid[i], K_FOREVER);
881 }
882 }
883
884 /**
885 * @brief Test semaphore timeout period
886 * @ingroup kernel_semaphore_tests
887 * @see k_sem_take(), k_sem_give(), k_sem_reset()
888 */
ZTEST(semaphore,test_sem_measure_timeouts)889 ZTEST(semaphore, test_sem_measure_timeouts)
890 {
891 int64_t start_ticks, end_ticks, diff_ticks;
892
893 k_sem_reset(&simple_sem);
894
895 /* with timeout of 1 sec */
896 start_ticks = k_uptime_get();
897
898 expect_k_sem_take_nomsg(&simple_sem, K_SECONDS(1), -EAGAIN);
899
900 end_ticks = k_uptime_get();
901
902 diff_ticks = end_ticks - start_ticks;
903
904 zassert_true((diff_ticks >= SEC2MS(1)),
905 "k_sem_take returned too early: %lld < %d",
906 diff_ticks, SEC2MS(1));
907
908 /* This subtest could fail spuriously if we happened to run the below right as
909 * a tick occurred. Unfortunately, we cannot actually fix this, because on some
910 * emulated platforms time does not advance while running the cpu, so
911 * if we spin and wait for a tick boundary we'll spin forever.
912 * The best we can do is hope that k_busy_wait finishes just after a tick boundary.
913 */
914 k_busy_wait(1);
915 start_ticks = k_uptime_get();
916
917 expect_k_sem_take_nomsg(&simple_sem, K_NO_WAIT, -EBUSY);
918
919 end_ticks = k_uptime_get();
920
921 diff_ticks = end_ticks - start_ticks;
922
923 zassert_true(end_ticks >= start_ticks,
924 "time went backwards: %lld -> %lld",
925 start_ticks, end_ticks);
926
927 zassert_true(diff_ticks >= 0,
928 "k_sem_take took too long: %lld != 0",
929 diff_ticks);
930 }
931
sem_measure_timeout_from_thread_helper(void * p1,void * p2,void * p3)932 void sem_measure_timeout_from_thread_helper(void *p1, void *p2, void *p3)
933 {
934 /* first sync the 2 threads */
935 k_sem_give(&simple_sem);
936
937 /* give the semaphore */
938 k_sem_give(&multiple_thread_sem);
939 }
940
941
942 /**
943 * @brief Test timeout of semaphore from thread
944 * @ingroup kernel_semaphore_tests
945 * @see k_sem_give(), k_sem_reset(), k_sem_take()
946 */
ZTEST(semaphore,test_sem_measure_timeout_from_thread)947 ZTEST(semaphore, test_sem_measure_timeout_from_thread)
948 {
949 int64_t start_ticks, end_ticks, diff_ticks;
950
951 k_sem_reset(&simple_sem);
952 k_sem_reset(&multiple_thread_sem);
953
954 /* give a semaphore from a thread and calculate the time taken */
955 k_thread_create(&sem_tid_1, stack_1, STACK_SIZE,
956 sem_measure_timeout_from_thread_helper,
957 NULL, NULL, NULL,
958 K_PRIO_PREEMPT(3), 0, K_NO_WAIT);
959
960
961 /* first sync the 2 threads */
962 expect_k_sem_take_nomsg(&simple_sem, K_FOREVER, 0);
963
964 /* with timeout of 1 sec */
965 start_ticks = k_uptime_get();
966
967 expect_k_sem_take_nomsg(&multiple_thread_sem, K_SECONDS(1), 0);
968
969 end_ticks = k_uptime_get();
970
971 diff_ticks = end_ticks - start_ticks;
972
973 zassert_true((diff_ticks < SEC2MS(1)),
974 "k_sem_take took too long: %d >= %d",
975 diff_ticks, SEC2MS(1));
976 k_thread_join(&sem_tid_1, K_FOREVER);
977 }
978
sem_multiple_take_and_timeouts_helper(void * p1,void * p2,void * p3)979 void sem_multiple_take_and_timeouts_helper(void *p1, void *p2, void *p3)
980 {
981 int timeout = POINTER_TO_INT(p1);
982 int64_t start_ticks, end_ticks, diff_ticks;
983
984 start_ticks = k_uptime_get();
985
986 expect_k_sem_take_nomsg(&simple_sem, K_MSEC(timeout), -EAGAIN);
987
988 end_ticks = k_uptime_get();
989
990 diff_ticks = end_ticks - start_ticks;
991
992 zassert_true(diff_ticks >= timeout,
993 "time mismatch - expected at least %d, got %lld",
994 timeout, diff_ticks);
995
996 k_pipe_write(&timeout_info_pipe, (uint8_t *)&timeout, sizeof(int), K_FOREVER);
997
998 }
999
1000 /**
1001 * @brief Test multiple semaphore take with timeouts
1002 * @ingroup kernel_semaphore_tests
1003 * @see k_sem_take(), k_sem_reset()
1004 */
ZTEST(semaphore_1cpu,test_sem_multiple_take_and_timeouts)1005 ZTEST(semaphore_1cpu, test_sem_multiple_take_and_timeouts)
1006 {
1007 if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) {
1008 ztest_test_skip();
1009 }
1010
1011 static uint32_t timeout;
1012
1013 k_sem_reset(&simple_sem);
1014 k_pipe_reset(&timeout_info_pipe);
1015
1016 /* Multiple threads timeout and the sequence in which it times out
1017 * is pushed into a pipe and checked later on.
1018 */
1019 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
1020 k_thread_create(&multiple_tid[i],
1021 multiple_stack[i], STACK_SIZE,
1022 sem_multiple_take_and_timeouts_helper,
1023 INT_TO_POINTER(QSEC2MS(i + 1)), NULL, NULL,
1024 K_PRIO_PREEMPT(1), 0, K_NO_WAIT);
1025 }
1026
1027 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
1028 k_pipe_read(&timeout_info_pipe, (uint8_t *)&timeout, sizeof(int), K_FOREVER);
1029 zassert_equal(timeout, QSEC2MS(i + 1),
1030 "timeout did not occur properly: %d != %d",
1031 timeout, QSEC2MS(i + 1));
1032 }
1033
1034 /* cleanup */
1035 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
1036 k_thread_join(&multiple_tid[i], K_FOREVER);
1037 }
1038 }
1039
sem_multi_take_timeout_diff_sem_helper(void * p1,void * p2,void * p3)1040 void sem_multi_take_timeout_diff_sem_helper(void *p1, void *p2, void *p3)
1041 {
1042 int rc;
1043 int timeout = POINTER_TO_INT(p1);
1044 struct k_sem *sema = p2;
1045 int64_t start_ticks, end_ticks, diff_ticks;
1046 struct timeout_info info = {
1047 .timeout = timeout,
1048 .sema = sema
1049 };
1050
1051 start_ticks = k_uptime_get();
1052
1053 expect_k_sem_take_nomsg(sema, K_MSEC(timeout), -EAGAIN);
1054
1055 end_ticks = k_uptime_get();
1056
1057 diff_ticks = end_ticks - start_ticks;
1058
1059 zassert_true(diff_ticks >= timeout,
1060 "time mismatch - expected at least %d, got %lld",
1061 timeout, diff_ticks);
1062
1063 rc = k_pipe_write(&timeout_info_pipe, (uint8_t *)&info, sizeof(struct timeout_info),
1064 K_FOREVER);
1065 zassert_true(rc == sizeof(struct timeout_info),
1066 "k_pipe_write failed: %d", rc);
1067 }
1068
1069 /**
1070 * @brief Test sequence of multiple semaphore timeouts
1071 * @ingroup kernel_semaphore_tests
1072 * @see k_sem_take(), k_sem_reset()
1073 */
ZTEST(semaphore,test_sem_multi_take_timeout_diff_sem)1074 ZTEST(semaphore, test_sem_multi_take_timeout_diff_sem)
1075 {
1076 int rc;
1077 if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) {
1078 ztest_test_skip();
1079 }
1080
1081 struct timeout_info seq_info[] = {
1082 { SEC2MS(2), &simple_sem },
1083 { SEC2MS(1), &multiple_thread_sem },
1084 { SEC2MS(3), &simple_sem },
1085 { SEC2MS(5), &multiple_thread_sem },
1086 { SEC2MS(4), &simple_sem },
1087 };
1088
1089 static struct timeout_info retrieved_info;
1090
1091 k_sem_reset(&simple_sem);
1092 k_sem_reset(&multiple_thread_sem);
1093 k_pipe_reset(&timeout_info_pipe);
1094 memset(&retrieved_info, 0, sizeof(struct timeout_info));
1095
1096 /* Multiple threads timeout on different semaphores and the sequence
1097 * in which it times out is pushed into a pipe and checked later on.
1098 */
1099 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
1100 k_thread_create(&multiple_tid[i],
1101 multiple_stack[i], STACK_SIZE,
1102 sem_multi_take_timeout_diff_sem_helper,
1103 INT_TO_POINTER(seq_info[i].timeout),
1104 seq_info[i].sema, NULL,
1105 K_PRIO_PREEMPT(1), 0, K_NO_WAIT);
1106 }
1107
1108 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
1109 rc = k_pipe_read(&timeout_info_pipe, (uint8_t *)&retrieved_info,
1110 sizeof(struct timeout_info), K_FOREVER);
1111 zassert_true(rc == sizeof(struct timeout_info),
1112 "k_pipe_read failed: %d", rc);
1113
1114 zassert_true(retrieved_info.timeout == SEC2MS(i + 1),
1115 "timeout did not occur properly");
1116 }
1117 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
1118 k_thread_join(&multiple_tid[i], K_FOREVER);
1119 }
1120 }
1121
1122 /**
1123 * @brief Test thread mutual exclusion by semaphore
1124 * @details Test is using to see how mutual exclusion is made by semaphore
1125 * Made two threads, with two functions which use common variable.
1126 * That variable is a critical section and can't be changed by two threads
1127 * at the same time.
1128 * @ingroup kernel_semaphore_tests
1129 */
ZTEST(semaphore_1cpu,test_sem_queue_mutual_exclusion)1130 ZTEST(semaphore_1cpu, test_sem_queue_mutual_exclusion)
1131 {
1132 critical_var = 0;
1133
1134 expect_k_sem_init_nomsg(&mut_sem, 0, 1, 0);
1135
1136 k_thread_create(&sem_tid_1, stack_1, STACK_SIZE,
1137 sem_queue_mutual_exclusion1, NULL, NULL,
1138 NULL, 1, 0,
1139 K_NO_WAIT);
1140
1141 k_thread_create(&sem_tid_2, stack_2, STACK_SIZE,
1142 sem_queue_mutual_exclusion2, NULL, NULL,
1143 NULL, 1, 0,
1144 K_NO_WAIT);
1145
1146 k_sleep(K_MSEC(100));
1147
1148 k_sem_give(&mut_sem);
1149 k_thread_join(&sem_tid_1, K_FOREVER);
1150 k_thread_join(&sem_tid_2, K_FOREVER);
1151 }
1152
1153 #ifdef CONFIG_USERSPACE
thread_sem_give_null(void * p1,void * p2,void * p3)1154 static void thread_sem_give_null(void *p1, void *p2, void *p3)
1155 {
1156 ARG_UNUSED(p1);
1157 ARG_UNUSED(p2);
1158 ARG_UNUSED(p3);
1159
1160 ztest_set_fault_valid(true);
1161 k_sem_give(NULL);
1162
1163 /* should not go here*/
1164 ztest_test_fail();
1165 }
1166
1167 /**
1168 * @brief Test k_sem_give() API
1169 *
1170 * @details Create a thread and set k_sem_give() input to NULL
1171 *
1172 * @ingroup kernel_semaphore_tests
1173 *
1174 * @see k_sem_give()
1175 */
ZTEST_USER(semaphore_null_case,test_sem_give_null)1176 ZTEST_USER(semaphore_null_case, test_sem_give_null)
1177 {
1178 k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
1179 thread_sem_give_null,
1180 NULL, NULL, NULL,
1181 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
1182 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
1183
1184 k_thread_join(tid, K_FOREVER);
1185 }
1186 #endif
1187
1188 #ifdef CONFIG_USERSPACE
thread_sem_init_null(void * p1,void * p2,void * p3)1189 static void thread_sem_init_null(void *p1, void *p2, void *p3)
1190 {
1191 ARG_UNUSED(p1);
1192 ARG_UNUSED(p2);
1193 ARG_UNUSED(p3);
1194
1195 ztest_set_fault_valid(true);
1196 k_sem_init(NULL, 0, 1);
1197
1198 /* should not go here*/
1199 ztest_test_fail();
1200 }
1201
1202 /**
1203 * @brief Test k_sem_init() API
1204 *
1205 * @details Create a thread and set k_sem_init() input to NULL
1206 *
1207 * @ingroup kernel_semaphore_tests
1208 *
1209 * @see k_sem_init()
1210 */
ZTEST_USER(semaphore_null_case,test_sem_init_null)1211 ZTEST_USER(semaphore_null_case, test_sem_init_null)
1212 {
1213 k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
1214 thread_sem_init_null,
1215 NULL, NULL, NULL,
1216 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
1217 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
1218
1219 k_thread_join(tid, K_FOREVER);
1220 }
1221 #endif
1222
1223 #ifdef CONFIG_USERSPACE
thread_sem_take_null(void * p1,void * p2,void * p3)1224 static void thread_sem_take_null(void *p1, void *p2, void *p3)
1225 {
1226 ARG_UNUSED(p1);
1227 ARG_UNUSED(p2);
1228 ARG_UNUSED(p3);
1229
1230 ztest_set_fault_valid(true);
1231 k_sem_take(NULL, K_MSEC(1));
1232
1233 /* should not go here*/
1234 ztest_test_fail();
1235 }
1236
1237 /**
1238 * @brief Test k_sem_take() API
1239 *
1240 * @details Create a thread and set k_sem_take() input to NULL
1241 *
1242 * @ingroup kernel_semaphore_tests
1243 *
1244 * @see k_sem_take()
1245 */
ZTEST_USER(semaphore_null_case,test_sem_take_null)1246 ZTEST_USER(semaphore_null_case, test_sem_take_null)
1247 {
1248 k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
1249 thread_sem_take_null,
1250 NULL, NULL, NULL,
1251 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
1252 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
1253
1254 k_thread_join(tid, K_FOREVER);
1255 }
1256 #endif
1257
1258 #ifdef CONFIG_USERSPACE
thread_sem_reset_null(void * p1,void * p2,void * p3)1259 static void thread_sem_reset_null(void *p1, void *p2, void *p3)
1260 {
1261 ARG_UNUSED(p1);
1262 ARG_UNUSED(p2);
1263 ARG_UNUSED(p3);
1264
1265 ztest_set_fault_valid(true);
1266 k_sem_reset(NULL);
1267
1268 /* should not go here*/
1269 ztest_test_fail();
1270 }
1271
1272 /**
1273 * @brief Test k_sem_reset() API
1274 *
1275 * @details Create a thread and set k_sem_reset() input to NULL
1276 *
1277 * @ingroup kernel_semaphore_tests
1278 *
1279 * @see k_sem_reset()
1280 */
ZTEST_USER(semaphore_null_case,test_sem_reset_null)1281 ZTEST_USER(semaphore_null_case, test_sem_reset_null)
1282 {
1283 k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
1284 thread_sem_reset_null,
1285 NULL, NULL, NULL,
1286 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
1287 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
1288
1289 k_thread_join(tid, K_FOREVER);
1290 }
1291 #endif
1292
1293 #ifdef CONFIG_USERSPACE
thread_sem_count_get_null(void * p1,void * p2,void * p3)1294 static void thread_sem_count_get_null(void *p1, void *p2, void *p3)
1295 {
1296 ARG_UNUSED(p1);
1297 ARG_UNUSED(p2);
1298 ARG_UNUSED(p3);
1299
1300 ztest_set_fault_valid(true);
1301 k_sem_count_get(NULL);
1302
1303 /* should not go here*/
1304 ztest_test_fail();
1305 }
1306
1307 /**
1308 * @brief Test k_sem_count_get() API
1309 *
1310 * @details Create a thread and set k_sem_count_get() input to NULL
1311 *
1312 * @ingroup kernel_semaphore_tests
1313 *
1314 * @see k_sem_count_get()
1315 */
ZTEST_USER(semaphore_null_case,test_sem_count_get_null)1316 ZTEST_USER(semaphore_null_case, test_sem_count_get_null)
1317 {
1318 k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
1319 thread_sem_count_get_null,
1320 NULL, NULL, NULL,
1321 K_PRIO_PREEMPT(THREAD_TEST_PRIORITY),
1322 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
1323
1324 k_thread_join(tid, K_FOREVER);
1325 }
1326 #endif
1327
test_init(void)1328 void *test_init(void)
1329 {
1330 #ifdef CONFIG_USERSPACE
1331 k_thread_access_grant(k_current_get(),
1332 &simple_sem, &multiple_thread_sem, &low_prio_sem,
1333 &mid_prio_sem, &high_prio_sem, &ksema, &msg_sema,
1334 &high_prio_long_sem, &stack_1, &stack_2,
1335 &stack_3, &stack_4, &timeout_info_pipe,
1336 &sem_tid_1, &sem_tid_2, &sem_tid_3,
1337 &sem_tid_4, &tstack, &tdata, &mut_sem,
1338 &statically_defined_sem);
1339 #endif
1340 return NULL;
1341 }
1342
1343 ZTEST_SUITE(semaphore, NULL, test_init, NULL, NULL, NULL);
1344 ZTEST_SUITE(semaphore_1cpu, NULL, NULL, ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
1345 ZTEST_SUITE(semaphore_null_case, NULL, test_init, NULL, NULL, NULL);
1346