1 /*
2 * Copyright 2023 Linaro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8
9 #define SLEEPTIME 10
10 #define STACKSIZE 1024
11 #define PRIORITY 7
12
loop_0(void)13 void __no_optimization loop_0(void)
14 {
15 /* Wait to spend some cycles */
16 k_busy_wait(10);
17 }
18
loop_1(void)19 void __no_optimization loop_1(void)
20 {
21 /* Wait to spend some cycles */
22 k_busy_wait(1000);
23 }
24
25 /*
26 * 'main' thread can take its mutex promptly and run. 'thread_A' needs to wait 'main' give its
27 * (thread_A) mutex to run.
28 */
29 K_SEM_DEFINE(main_sem, 1, 1); /* Initialized as ready to be taken */
30 K_SEM_DEFINE(thread_a_sem, 0, 1); /* Initialized as already taken (blocked) */
31
32 K_THREAD_STACK_DEFINE(thread_a_stack, STACKSIZE);
33 static struct k_thread thread_a_data;
34
35 static int counter;
36
get_sem_and_exec_function(struct k_sem * my_sem,struct k_sem * other_sem,void (* func)(void))37 void get_sem_and_exec_function(struct k_sem *my_sem, struct k_sem *other_sem, void (*func)(void))
38 {
39 while (counter < 4) {
40 k_sem_take(my_sem, K_FOREVER);
41
42 func();
43 k_msleep(SLEEPTIME);
44
45 counter++;
46 k_sem_give(other_sem);
47 }
48 }
49
thread_A(void * notused0,void * notused1,void * notused2)50 void thread_A(void *notused0, void *notused1, void *notused2)
51 {
52 ARG_UNUSED(notused0);
53 ARG_UNUSED(notused1);
54 ARG_UNUSED(notused2);
55
56 get_sem_and_exec_function(&thread_a_sem, &main_sem, loop_0);
57 }
58
main(void)59 int main(void)
60 {
61 k_tid_t thread_a;
62
63 /* Create Thread A */
64 thread_a = k_thread_create(&thread_a_data, thread_a_stack, STACKSIZE,
65 thread_A, NULL, NULL, NULL, PRIORITY, 0, K_NO_WAIT);
66
67 k_thread_name_set(thread_a, "thread_A");
68
69 /* Start ping-pong between 'main' and 'thread_A' */
70 get_sem_and_exec_function(&main_sem, &thread_a_sem, loop_1);
71
72 return 0;
73 }
74