zpp
Zephyr C++20 Framework
main.cpp
Go to the documentation of this file.
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 #include <zephyr/sys/arch_interface.h>
10 
11 #include <zpp.hpp>
12 #include <chrono>
13 
14 #define NUM_THREADS 20
15 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
16 
17 namespace {
18 
19 zpp::mutex m;
21 
22 
26 
27 int done{};
28 
29 void worker_thread(int myid) noexcept
30 {
31  const int workloops = 5;
32 
33  for (int i = 0; i < workloops; i++) {
34  printk("[thread %d] working (%d/%d)\n", myid, i, workloops);
35 
36  zpp::this_thread::sleep_for(std::chrono::milliseconds(500));
37  }
38 
39  //
40  // we're going to manipulate done and use the cond, so we need the mutex
41  //
42  zpp::lock_guard lg(m);
43 
44  //
45  // increase the count of threads that have finished their work.
46  //
47  done++;
48  printk("[thread %d] done is now %d. Signalling cond.\n", myid, done);
49 
50  auto res = cv.notify_one();
51  __ASSERT_NO_MSG(res == true);
52 }
53 
54 } // anonimouse namespace
55 
56 int main(void)
57 {
58  const zpp::thread_attr attrs(
62  );
63 
64  for (int i = 0; i < NUM_THREADS; i++) {
65  t[i] = zpp::thread(tcb[i], tstack(i), attrs, &worker_thread, i);
66  }
67 
68  //zpp::this_thread::sleep_for(std::chrono::seconds(1));
69 
70  printk("[thread %s] all threads started\n", __func__);
71 
72  {
73  zpp::lock_guard lg(m);
74 
75  //
76  // are the other threads still busy?
77  //
78  while (done < NUM_THREADS) {
79  printk("[thread %s] done is %d which is < %d so waiting on cond\n",
80  __func__, done, (int)NUM_THREADS);
81 
82  // block this thread until another thread signals cond. While
83  // blocked, the mutex is released, then re-acquired before this
84  // thread is woken up and the call returns.
85  auto res = cv.wait(m);
86  __ASSERT_NO_MSG(res == true);
87 
88  printk("[thread %s] wake - cond was signalled.\n", __func__);
89 
90  // we go around the loop with the lock held
91  }
92 
93  } // zpp::lock_guard scope
94 
95  for (int i = 0; i < NUM_THREADS; i++) {
96  auto res = t[i].join();
97  __ASSERT_NO_MSG(res == true);
98  }
99 
100  printk("[thread %s] done == %d so everyone is done\n",
101  __func__, (int)NUM_THREADS);
102 
103  return 0;
104 }
auto notify_one() noexcept
Notify one waiter.
A condition variable class.
lock_guard using zpp::mutex as a lock.
Definition: lock_guard.hpp:23
A recursive mutex class.
Definition: mutex.hpp:150
Thread creation attributes.
Definition: thread_attr.hpp:35
thread_data holds the stack and thread control block memory
Definition: thread_data.hpp:19
static constexpr thread_prio preempt(int prio) noexcept
Create a preemptive priority value.
The class thread repecents a single Zephyr thread.
Definition: thread.hpp:147
auto sleep_for(const std::chrono::duration< T_Rep, T_Period > &sleep_duration)
Suspend the current thread for a specified time duration.
Definition: thread.hpp:77
int main(int argc, char *argv[])
Definition: main.cpp:26
#define STACK_SIZE
Definition: main.cpp:15
#define NUM_THREADS
Definition: main.cpp:14
#define ZPP_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size)