1 /*
2 * Copyright (c) 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/arch/cpu.h>
9
10 #define NUM_THREADS 20
11 #define STACK_SIZE (1024)
12
13 K_THREAD_STACK_ARRAY_DEFINE(tstacks, NUM_THREADS, STACK_SIZE);
14
15 static struct k_thread t[NUM_THREADS];
16
17 K_MUTEX_DEFINE(mutex);
18 K_CONDVAR_DEFINE(condvar);
19
20 static int done;
21
worker_thread(void * p1,void * p2,void * p3)22 void worker_thread(void *p1, void *p2, void *p3)
23 {
24 const int myid = (long)p1;
25 const int workloops = 5;
26
27 for (int i = 0; i < workloops; i++) {
28 printk("[thread %d] working (%d/%d)\n", myid, i, workloops);
29 k_sleep(K_MSEC(500));
30 }
31
32 /*
33 * we're going to manipulate done and use the cond, so we need the mutex
34 */
35 k_mutex_lock(&mutex, K_FOREVER);
36
37 /*
38 * increase the count of threads that have finished their work.
39 */
40 done++;
41 printk("[thread %d] done is now %d. Signalling cond.\n", myid, done);
42
43 k_condvar_signal(&condvar);
44 k_mutex_unlock(&mutex);
45 }
46
main(void)47 int main(void)
48 {
49 k_tid_t tid[NUM_THREADS];
50
51 done = 0;
52
53 for (int i = 0; i < NUM_THREADS; i++) {
54 tid[i] =
55 k_thread_create(&t[i], tstacks[i], STACK_SIZE,
56 worker_thread, INT_TO_POINTER(i), NULL,
57 NULL, K_PRIO_PREEMPT(10), 0, K_NO_WAIT);
58 }
59 k_sleep(K_MSEC(1000));
60
61 k_mutex_lock(&mutex, K_FOREVER);
62
63 /*
64 * are the other threads still busy?
65 */
66 while (done < NUM_THREADS) {
67 printk("[thread %s] done is %d which is < %d so waiting on cond\n",
68 __func__, done, (int)NUM_THREADS);
69
70 /* block this thread until another thread signals cond. While
71 * blocked, the mutex is released, then re-acquired before this
72 * thread is woken up and the call returns.
73 */
74 k_condvar_wait(&condvar, &mutex, K_FOREVER);
75
76 printk("[thread %s] wake - cond was signalled.\n", __func__);
77
78 /* we go around the loop with the lock held */
79 }
80
81 printk("[thread %s] done == %d so everyone is done\n",
82 __func__, (int)NUM_THREADS);
83
84 k_mutex_unlock(&mutex);
85 return 0;
86 }
87