1 /*
2 * Copyright (c) 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8 #include <zephyr/ztest.h>
9 #include <zephyr/irq_offload.h>
10 #include <zephyr/ztest_error_hook.h>
11
12 #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
13
14 #define PRIO_WAIT (CONFIG_ZTEST_THREAD_PRIORITY)
15 #define PRIO_WAKE (CONFIG_ZTEST_THREAD_PRIORITY)
16
17 K_THREAD_STACK_DEFINE(stack_1, STACK_SIZE);
18 K_THREAD_STACK_DEFINE(condvar_wake_stack, STACK_SIZE);
19
20 struct k_thread condvar_tid;
21 struct k_thread condvar_wake_tid;
22
23 struct k_condvar simple_condvar;
24 K_MUTEX_DEFINE(test_mutex);
25
26 #define TOTAL_THREADS_WAITING (3)
27 #define TCOUNT 10
28 #define COUNT_LIMIT 12
29
30 ZTEST_BMEM int woken;
31 ZTEST_BMEM int timeout;
32 ZTEST_BMEM int index[TOTAL_THREADS_WAITING];
33 ZTEST_BMEM int count;
34
35 struct k_condvar multiple_condvar[TOTAL_THREADS_WAITING];
36
37 struct k_thread multiple_tid[TOTAL_THREADS_WAITING];
38 struct k_thread multiple_wake_tid[TOTAL_THREADS_WAITING];
39 K_THREAD_STACK_ARRAY_DEFINE(multiple_stack,
40 TOTAL_THREADS_WAITING, STACK_SIZE);
41 K_THREAD_STACK_ARRAY_DEFINE(multiple_wake_stack,
42 TOTAL_THREADS_WAITING, STACK_SIZE);
43
44
45 /******************************************************************************/
46 /* Helper functions */
condvar_isr_wake(const void * condvar)47 void condvar_isr_wake(const void *condvar)
48 {
49 k_condvar_signal((struct k_condvar *)condvar);
50 }
51
condvar_wake_from_isr(struct k_condvar * condvar)52 void condvar_wake_from_isr(struct k_condvar *condvar)
53 {
54 irq_offload(condvar_isr_wake, (const void *)condvar);
55 }
56
57 /* test condvar wait, no condvar wake */
condvar_wait_task(void * p1,void * p2,void * p3)58 void condvar_wait_task(void *p1, void *p2, void *p3)
59 {
60 int32_t ret_value;
61 k_ticks_t time_val = *(int *)p1;
62
63 k_condvar_init(&simple_condvar);
64 zassert_true(time_val >= (int)K_TICKS_FOREVER,
65 "invalid timeout parameter");
66
67 k_mutex_lock(&test_mutex, K_FOREVER);
68 ret_value = k_condvar_wait(&simple_condvar, &test_mutex, K_TICKS(time_val));
69
70 switch (time_val) {
71 case K_TICKS_FOREVER:
72 zassert_true(ret_value == 0,
73 "k_condvar_wait failed.");
74 zassert_false(ret_value == 0,
75 "condvar wait task wakeup.");
76 break;
77 case 0:
78 zassert_true(ret_value == -EAGAIN,
79 "k_condvar_wait failed.");
80 break;
81 default:
82 zassert_true(ret_value == -EAGAIN,
83 "k_condvar_wait failed.: %d", ret_value);
84 break;
85 }
86
87 k_mutex_unlock(&test_mutex);
88
89 }
90
condvar_wake_task(void * p1,void * p2,void * p3)91 void condvar_wake_task(void *p1, void *p2, void *p3)
92 {
93 int32_t ret_value;
94
95 ret_value = k_condvar_signal(&simple_condvar);
96 zassert_equal(ret_value, 0,
97 "k_condvar_wake failed. (%d!=%d)", ret_value, 0);
98 }
99
condvar_wake_multiple(void * p1,void * p2,void * p3)100 void condvar_wake_multiple(void *p1, void *p2, void *p3)
101 {
102 int32_t ret_value;
103 int woken_num = *(int *)p1;
104
105 ret_value = k_condvar_broadcast(&simple_condvar);
106 zassert_true(ret_value == woken_num,
107 "k_condvar_wake failed. (%d!=%d)", ret_value, woken_num);
108 }
109
condvar_wait_wake_task(void * p1,void * p2,void * p3)110 void condvar_wait_wake_task(void *p1, void *p2, void *p3)
111 {
112 int32_t ret_value;
113 int time_val = *(int *)p1;
114
115 zassert_true(time_val >= (int)K_TICKS_FOREVER, "invalid timeout parameter");
116 k_mutex_lock(&test_mutex, K_FOREVER);
117 ret_value = k_condvar_wait(&simple_condvar, &test_mutex, K_TICKS(time_val));
118
119 switch (time_val) {
120 case K_TICKS_FOREVER:
121 zassert_true(ret_value == 0,
122 "k_condvar_wait failed.");
123 break;
124 case 0:
125 zassert_true(ret_value == -EAGAIN,
126 "k_condvar_wait failed.");
127 break;
128 default:
129 zassert_true(ret_value == 0,
130 "k_condvar_wait failed.");
131 break;
132 }
133
134 k_mutex_unlock(&test_mutex);
135 }
136 /**
137 * @defgroup kernel_condvar_tests Condition Variables
138 * @ingroup all_tests
139 * @{
140 * @}
141 *
142 * @addtogroup kernel_condvar_tests
143 * @{
144 */
145 /**
146 * @brief Test k_condvar_wait() and k_condvar_wake()
147 */
ZTEST_USER(condvar_tests,test_condvar_wait_forever_wake)148 ZTEST_USER(condvar_tests, test_condvar_wait_forever_wake)
149 {
150 woken = 1;
151 timeout = K_TICKS_FOREVER;
152
153 k_condvar_init(&simple_condvar);
154 k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
155 condvar_wait_wake_task, &timeout, NULL, NULL,
156 PRIO_WAIT, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
157
158 /* giving time for the condvar_wait_wake_task to execute */
159 k_yield();
160
161 k_thread_create(&condvar_wake_tid, condvar_wake_stack, STACK_SIZE,
162 condvar_wake_task, &woken, NULL, NULL,
163 PRIO_WAKE, K_USER | K_INHERIT_PERMS, K_MSEC(1));
164
165 /* giving time for the condvar_wake_task
166 * and condvar_wait_wake_task to execute
167 */
168 k_yield();
169
170 k_thread_abort(&condvar_wake_tid);
171 k_thread_abort(&condvar_tid);
172 }
173
174 /**
175 * @brief Test k_condvar_wait() and k_condvar_wake() with timeout
176 */
ZTEST_USER(condvar_tests,test_condvar_wait_timeout_wake)177 ZTEST_USER(condvar_tests, test_condvar_wait_timeout_wake)
178 {
179 woken = 1;
180 timeout = k_ms_to_ticks_ceil32(100);
181
182 k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
183 condvar_wait_wake_task, &timeout, NULL, NULL,
184 PRIO_WAIT, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
185
186 /* giving time for the condvar_wait_wake_task to execute */
187 k_yield();
188
189 k_thread_create(&condvar_wake_tid, condvar_wake_stack, STACK_SIZE,
190 condvar_wake_task, &woken, NULL, NULL,
191 PRIO_WAKE, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
192
193 /*
194 * giving time for the condvar_wake_task
195 * and condvar_wait_wake_task to execute
196 */
197 k_yield();
198
199
200 k_thread_abort(&condvar_wake_tid);
201 k_thread_abort(&condvar_tid);
202 }
203
204 /**
205 * @brief Test k_condvar_wait() and k_condvar_wake() with timeout
206 */
ZTEST_USER(condvar_tests,test_condvar_wait_timeout)207 ZTEST_USER(condvar_tests, test_condvar_wait_timeout)
208 {
209 timeout = k_ms_to_ticks_ceil32(50);
210
211 k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
212 condvar_wait_task, &timeout, NULL, NULL,
213 PRIO_WAIT, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
214
215 /* giving time for the condvar_wait_task to execute */
216 k_sleep(K_MSEC(100));
217
218 k_thread_abort(&condvar_tid);
219 }
220
221
222 /**
223 * @brief Test k_condvar_wait() forever
224 */
ZTEST_USER(condvar_tests,test_condvar_wait_forever)225 ZTEST_USER(condvar_tests, test_condvar_wait_forever)
226 {
227 timeout = K_TICKS_FOREVER;
228
229
230 k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
231 condvar_wait_task, &timeout, NULL, NULL,
232 PRIO_WAIT, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
233
234 /* giving time for the condvar_wait_task to execute */
235 k_yield();
236
237 k_thread_abort(&condvar_tid);
238 }
239
240 /**
241 * @brief Test k_condvar_wait() with no wait
242 */
ZTEST_USER(condvar_tests,test_condvar_wait_nowait)243 ZTEST_USER(condvar_tests, test_condvar_wait_nowait)
244 {
245 timeout = 0;
246
247 k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
248 condvar_wait_task, &timeout, NULL, NULL,
249 PRIO_WAIT, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
250
251 /* giving time for the condvar_wait_task to execute */
252 k_sleep(K_MSEC(100));
253
254 k_thread_abort(&condvar_tid);
255 }
256
257
258 /**
259 * @brief Test case for conditional variable wait and wake functionality.
260 *
261 * This test validates the behavior of conditional variables when a thread
262 * waits on a condition and another thread wakes it up.
263 */
ZTEST_USER(condvar_tests,test_condvar_wait_nowait_wake)264 ZTEST_USER(condvar_tests, test_condvar_wait_nowait_wake)
265 {
266 woken = 0;
267 timeout = 0;
268
269 k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
270 condvar_wait_wake_task, &timeout, NULL, NULL,
271 PRIO_WAIT, K_USER | K_INHERIT_PERMS,
272 K_NO_WAIT);
273
274 /* giving time for the condvar_wait_wake_task to execute */
275 k_sleep(K_MSEC(100));
276
277 k_thread_create(&condvar_wake_tid, condvar_wake_stack, STACK_SIZE,
278 condvar_wake_task, &woken, NULL, NULL,
279 PRIO_WAKE, K_USER | K_INHERIT_PERMS,
280 K_NO_WAIT);
281
282 /* giving time for the condvar_wake_task to execute */
283 k_yield();
284
285 k_thread_abort(&condvar_wake_tid);
286 k_thread_abort(&condvar_tid);
287 }
288
289
290 /**
291 * @brief Test case for condition variable wait and wake functionality.
292 *
293 * This test verifies the behavior of a thread waiting on a condition variable
294 * with an infinite timeout and being woken up from an interrupt service routine (ISR).
295 *
296 */
ZTEST(condvar_tests,test_condvar_wait_forever_wake_from_isr)297 ZTEST(condvar_tests, test_condvar_wait_forever_wake_from_isr)
298 {
299 timeout = K_TICKS_FOREVER;
300
301 k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
302 condvar_wait_wake_task, &timeout, NULL, NULL,
303 PRIO_WAIT, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
304
305 /* giving time for the condvar_wait_wake_task to execute */
306 k_yield();
307
308 condvar_wake_from_isr(&simple_condvar);
309
310 /* giving time for the condvar_wait_wake_task to execute */
311 k_yield();
312
313 k_thread_abort(&condvar_tid);
314 }
315
316 /**
317 * @brief Test case for multiple threads waiting and waking on a condition variable.
318 *
319 * This test initializes a condition variable and creates multiple threads that
320 * wait on the condition variable. Another thread is created to wake up the
321 * waiting threads. The test ensures proper synchronization and behavior of
322 * threads waiting and waking on the condition variable.
323
324 */
ZTEST_USER(condvar_tests,test_condvar_multiple_threads_wait_wake)325 ZTEST_USER(condvar_tests, test_condvar_multiple_threads_wait_wake)
326 {
327 timeout = K_TICKS_FOREVER;
328 woken = TOTAL_THREADS_WAITING;
329
330 k_condvar_init(&simple_condvar);
331 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
332
333 k_thread_create(&multiple_tid[i], multiple_stack[i],
334 STACK_SIZE, condvar_wait_wake_task,
335 &timeout, NULL, NULL,
336 PRIO_WAIT, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
337 }
338
339 /* giving time for the other threads to execute */
340 k_yield();
341
342 k_thread_create(&condvar_wake_tid, condvar_wake_stack,
343 STACK_SIZE, condvar_wake_multiple, &woken,
344 NULL, NULL, PRIO_WAKE,
345 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
346
347 /* giving time for the other threads to execute */
348 k_yield();
349
350 k_thread_abort(&condvar_wake_tid);
351 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
352 k_thread_abort(&multiple_tid[i]);
353 }
354 }
355
356
condvar_multiple_wait_wake_task(void * p1,void * p2,void * p3)357 void condvar_multiple_wait_wake_task(void *p1, void *p2, void *p3)
358 {
359 int32_t ret_value;
360 int time_val = *(int *)p1;
361 int idx = *(int *)p2;
362
363 k_condvar_init(&multiple_condvar[idx]);
364
365 zassert_true(time_val == (int)K_TICKS_FOREVER, "invalid timeout parameter");
366 k_mutex_lock(&test_mutex, K_FOREVER);
367
368 ret_value = k_condvar_wait(&multiple_condvar[idx],
369 &test_mutex, K_TICKS(time_val));
370 zassert_true(ret_value == 0, "k_condvar_wait failed.");
371
372 k_mutex_unlock(&test_mutex);
373 }
374
condvar_multiple_wake_task(void * p1,void * p2,void * p3)375 void condvar_multiple_wake_task(void *p1, void *p2, void *p3)
376 {
377 int32_t ret_value;
378 int woken_num = *(int *)p1;
379 int idx = *(int *)p2;
380
381 zassert_true(woken_num > 0, "invalid woken number");
382
383 if (woken > 1) {
384 ret_value = k_condvar_signal(&multiple_condvar[idx]);
385 } else {
386 ret_value = k_condvar_broadcast(&multiple_condvar[idx]);
387 }
388
389 zassert_true(ret_value == woken_num, "k_condvar_wake failed. (%d!=%d)",
390 ret_value, woken_num);
391 }
392
393
394 /**
395 * @brief Test multiple threads waiting and waking on a condition variable.
396 *
397 * This test creates multiple threads that wait on a condition variable and
398 * another set of threads that wake them up. It ensures that the condition
399 * variable mechanism works correctly when multiple threads are involved.
400
401 */
ZTEST_USER(condvar_tests,test_multiple_condvar_wait_wake)402 ZTEST_USER(condvar_tests, test_multiple_condvar_wait_wake)
403 {
404 woken = 1;
405 timeout = K_TICKS_FOREVER;
406
407 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
408 index[i] = i;
409
410 k_thread_create(&multiple_tid[i], multiple_stack[i],
411 STACK_SIZE, condvar_multiple_wait_wake_task,
412 &timeout, &index[i], NULL, PRIO_WAIT,
413 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
414 }
415
416 /* giving time for the other threads to execute */
417 k_msleep(10);
418
419 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
420 k_thread_create(&multiple_wake_tid[i], multiple_wake_stack[i],
421 STACK_SIZE, condvar_multiple_wake_task,
422 &woken, &index[i], NULL, PRIO_WAKE,
423 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
424 }
425
426 /* giving time for the other threads to execute */
427 k_yield();
428
429 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
430 ;
431 }
432
433 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
434 k_thread_abort(&multiple_tid[i]);
435 k_thread_abort(&multiple_wake_tid[i]);
436 }
437 }
438
439 #ifdef CONFIG_USERSPACE
cond_init_null(void * p1,void * p2,void * p3)440 static void cond_init_null(void *p1, void *p2, void *p3)
441 {
442 ARG_UNUSED(p1);
443 ARG_UNUSED(p2);
444 ARG_UNUSED(p3);
445
446 ztest_set_fault_valid(true);
447 k_condvar_init(NULL);
448
449 /* should not go here*/
450 ztest_test_fail();
451 }
452
453
454 /**
455 * @brief Test case for conditional variable initialization with a null parameter.
456 *
457 * This test verifies the behavior of the conditional variable initialization
458 * when a null parameter is passed. It creates a thread to execute the
459 * `cond_init_null` function and ensures the thread completes execution.
460 */
ZTEST_USER(condvar_tests,test_condvar_init_null)461 ZTEST_USER(condvar_tests, test_condvar_init_null)
462 {
463 k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
464 cond_init_null,
465 NULL, NULL, NULL,
466 K_PRIO_PREEMPT(0),
467 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
468
469 k_thread_join(tid, K_FOREVER);
470 }
471 #else
ZTEST_USER(condvar_tests,test_condvar_init_null)472 ZTEST_USER(condvar_tests, test_condvar_init_null)
473 {
474 ztest_test_skip();
475 }
476 #endif
477
478 #ifdef CONFIG_USERSPACE
cond_signal_null(void * p1,void * p2,void * p3)479 static void cond_signal_null(void *p1, void *p2, void *p3)
480 {
481 ARG_UNUSED(p1);
482 ARG_UNUSED(p2);
483 ARG_UNUSED(p3);
484
485 ztest_set_fault_valid(true);
486 k_condvar_signal(NULL);
487
488 /* should not go here*/
489 ztest_test_fail();
490 }
491
cond_broadcast_null(void * p1,void * p2,void * p3)492 static void cond_broadcast_null(void *p1, void *p2, void *p3)
493 {
494 ARG_UNUSED(p1);
495 ARG_UNUSED(p2);
496 ARG_UNUSED(p3);
497
498 ztest_set_fault_valid(true);
499 k_condvar_broadcast(NULL);
500
501 /* should not go here*/
502 ztest_test_fail();
503 }
504
cond_wait_null(void * p1,void * p2,void * p3)505 static void cond_wait_null(void *p1, void *p2, void *p3)
506 {
507 ARG_UNUSED(p1);
508 ARG_UNUSED(p2);
509 ARG_UNUSED(p3);
510
511 ztest_set_fault_valid(true);
512 k_condvar_wait(NULL, NULL, K_FOREVER);
513
514 /* should not go here*/
515 ztest_test_fail();
516 }
517 /**
518 * @brief Test case for signaling a condition variable with a NULL parameter.
519 *
520 * This test creates a thread that attempts to signal a condition variable
521 * with a NULL parameter. It ensures that the system handles this scenario
522 * gracefully without causing unexpected behavior or crashes.
523 */
ZTEST_USER(condvar_tests,test_condvar_signal_null)524 ZTEST_USER(condvar_tests, test_condvar_signal_null)
525 {
526 k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
527 cond_signal_null,
528 NULL, NULL, NULL,
529 K_PRIO_PREEMPT(0),
530 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
531 k_thread_join(tid, K_FOREVER);
532 }
533
534 /**
535 * @brief Test case for broadcasting a condition variable with a NULL parameter.
536 *
537 * This test creates a thread that attempts to broadcast a condition variable
538 * with a NULL parameter. It verifies that the system can handle this edge case
539 * correctly and does not result in undefined behavior.
540 */
ZTEST_USER(condvar_tests,test_condvar_broadcast_null)541 ZTEST_USER(condvar_tests, test_condvar_broadcast_null)
542 {
543 k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
544 cond_broadcast_null,
545 NULL, NULL, NULL,
546 K_PRIO_PREEMPT(0),
547 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
548
549 k_thread_join(tid, K_FOREVER);
550 }
551
552 /**
553 * @brief Test case for waiting on a condition variable with a NULL parameter.
554 *
555 * This test creates a thread that attempts to wait on a condition variable
556 * with a NULL parameter. It ensures that the system properly handles this
557 * invalid operation and maintains stability.
558 */
ZTEST_USER(condvar_tests,test_condvar_wait_null)559 ZTEST_USER(condvar_tests, test_condvar_wait_null)
560 {
561 k_tid_t tid = k_thread_create(&condvar_tid, stack_1, STACK_SIZE,
562 cond_wait_null,
563 NULL, NULL, NULL,
564 K_PRIO_PREEMPT(0),
565 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
566 k_thread_join(tid, K_FOREVER);
567 }
568
569 #else
ZTEST_USER(condvar_tests,test_condvar_signal_null)570 ZTEST_USER(condvar_tests, test_condvar_signal_null)
571 {
572 ztest_test_skip();
573 }
ZTEST_USER(condvar_tests,test_condvar_broadcast_null)574 ZTEST_USER(condvar_tests, test_condvar_broadcast_null)
575 {
576 ztest_test_skip();
577 }
ZTEST_USER(condvar_tests,test_condvar_wait_null)578 ZTEST_USER(condvar_tests, test_condvar_wait_null)
579 {
580 ztest_test_skip();
581 }
582 #endif
583
584
inc_count(void * p1,void * p2,void * p3)585 void inc_count(void *p1, void *p2, void *p3)
586 {
587 int i;
588 long multi = (long)p2;
589
590 for (i = 0; i < TCOUNT; i++) {
591 k_mutex_lock(&test_mutex, K_FOREVER);
592 count++;
593
594 if (count == COUNT_LIMIT) {
595 if (multi) {
596 k_condvar_broadcast(&simple_condvar);
597 } else {
598 k_condvar_signal(&simple_condvar);
599 }
600 }
601
602 k_mutex_unlock(&test_mutex);
603
604 /* Sleep so threads can alternate on mutex lock */
605 k_sleep(K_MSEC(50));
606 }
607 }
608
watch_count(void * p1,void * p2,void * p3)609 void watch_count(void *p1, void *p2, void *p3)
610 {
611 long my_id = (long)p1;
612
613 printk("Starting %s: thread %ld\n", __func__, my_id);
614
615 k_mutex_lock(&test_mutex, K_FOREVER);
616 while (count < COUNT_LIMIT) {
617 k_condvar_wait(&simple_condvar, &test_mutex, K_FOREVER);
618 }
619 count += 125;
620 k_mutex_unlock(&test_mutex);
621 }
622
_condvar_usecase(long multi)623 void _condvar_usecase(long multi)
624 {
625 long t1 = 1, t2 = 2, t3 = 3;
626 int i;
627
628 count = 0;
629
630 /* Reinit mutex to prevent affection from previous testcases */
631 k_mutex_init(&test_mutex);
632
633 k_thread_create(&multiple_tid[0], multiple_stack[0], STACK_SIZE, watch_count,
634 INT_TO_POINTER(t1), NULL, NULL, K_PRIO_PREEMPT(10),
635 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
636
637 k_thread_create(&multiple_tid[1], multiple_stack[1], STACK_SIZE, inc_count,
638 INT_TO_POINTER(t2), INT_TO_POINTER(multi), NULL, K_PRIO_PREEMPT(10),
639 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
640
641 k_thread_create(&multiple_tid[2], multiple_stack[2], STACK_SIZE, inc_count,
642 INT_TO_POINTER(t3), INT_TO_POINTER(multi), NULL, K_PRIO_PREEMPT(10),
643 K_USER | K_INHERIT_PERMS, K_NO_WAIT);
644
645 /* Wait for all threads to complete */
646 for (i = 0; i < 3; i++) {
647 k_thread_join(&multiple_tid[i], K_FOREVER);
648 }
649
650 zassert_equal(count, 145, "Count not equal to 145");
651
652 }
653
654
655 /**
656 * @brief Test case for conditional variable use case with signal
657 *
658 * This test verifies the behavior of a conditional variable in a specific
659 * use case where a signal is used. It ensures that the conditional variable
660 * operates correctly when signaled, validating synchronization mechanisms.
661 */
ZTEST_USER(condvar_tests,test_condvar_usecase_signal)662 ZTEST_USER(condvar_tests, test_condvar_usecase_signal)
663 {
664 _condvar_usecase(0);
665 }
666
667
ZTEST_USER(condvar_tests,test_condvar_usecase_broadcast)668 ZTEST_USER(condvar_tests, test_condvar_usecase_broadcast)
669 {
670 _condvar_usecase(1);
671 }
672
673 /*test case main entry*/
condvar_tests_setup(void)674 static void *condvar_tests_setup(void)
675 {
676 #ifdef CONFIG_USERSPACE
677 k_thread_access_grant(k_current_get(), &test_mutex, &condvar_tid, &condvar_wake_tid,
678 &simple_condvar, &stack_1, &condvar_wake_stack);
679
680 for (int i = 0; i < TOTAL_THREADS_WAITING; i++) {
681 k_thread_access_grant(k_current_get(),
682 &multiple_tid[i],
683 &multiple_wake_tid[i],
684 &multiple_stack[i],
685 &multiple_condvar[i],
686 &multiple_wake_stack[i]);
687 }
688 #endif
689 return NULL;
690 }
691
692 /**
693 * @}
694 */
695
696 ZTEST_SUITE(condvar_tests, NULL, condvar_tests_setup, NULL, NULL, NULL);
697