Loading...
/* * Copyright (c) 2020 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr.h> #include <arch/cpu.h> #include <sys/arch_interface.h> #define NUM_THREADS 20 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACKSIZE) K_THREAD_STACK_EXTERN(tstack); K_THREAD_STACK_ARRAY_DEFINE(tstacks, NUM_THREADS, STACK_SIZE); static struct k_thread t[NUM_THREADS]; K_MUTEX_DEFINE(mutex); K_CONDVAR_DEFINE(condvar); static int done; void worker_thread(void *p1, void *p2, void *p3) { const int myid = (long)p1; const int workloops = 5; for (int i = 0; i < workloops; i++) { printk("[thread %d] working (%d/%d)\n", myid, i, workloops); k_sleep(K_MSEC(500)); } /* * we're going to manipulate done and use the cond, so we need the mutex */ k_mutex_lock(&mutex, K_FOREVER); /* * increase the count of threads that have finished their work. */ done++; printk("[thread %d] done is now %d. Signalling cond.\n", myid, done); k_condvar_signal(&condvar); k_mutex_unlock(&mutex); } void main(void) { k_tid_t tid[NUM_THREADS]; done = 0; for (int i = 0; i < NUM_THREADS; i++) { tid[i] = k_thread_create(&t[i], tstacks[i], STACK_SIZE, worker_thread, INT_TO_POINTER(i), NULL, NULL, K_PRIO_PREEMPT(10), 0, K_NO_WAIT); } k_sleep(K_MSEC(1000)); k_mutex_lock(&mutex, K_FOREVER); /* * are the other threads still busy? */ while (done < NUM_THREADS) { printk("[thread %s] done is %d which is < %d so waiting on cond\n", __func__, done, (int)NUM_THREADS); /* block this thread until another thread signals cond. While * blocked, the mutex is released, then re-acquired before this * thread is woken up and the call returns. */ k_condvar_wait(&condvar, &mutex, K_FOREVER); printk("[thread %s] wake - cond was signalled.\n", __func__); /* we go around the loop with the lock held */ } printk("[thread %s] done == %d so everyone is done\n", __func__, (int)NUM_THREADS); k_mutex_unlock(&mutex); } |