SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_sync_barrier.h
Go to the documentation of this file.
1/*
2 * SuperTinyKernel(TM) RTOS: Lightweight High-Performance Deterministic C++ RTOS for Embedded Systems.
3 *
4 * Source: https://github.com/SuperTinyKernel-RTOS
5 *
6 * Copyright (c) 2022-2026 Neutron Code Limited <stk@neutroncode.com>. All Rights Reserved.
7 * License: MIT License, see LICENSE for a full text.
8 */
9
10#ifndef STK_SYNC_BARRIER_H_
11#define STK_SYNC_BARRIER_H_
12
13#include "stk_sync_mutex.h"
14#include "stk_sync_cv.h"
15
19
20namespace stk {
21namespace sync {
22
54class Barrier final : public ITraceable
55{
56public:
70
75 explicit Barrier(uint32_t count) : m_threshold(count), m_count(count), m_generation(0U)
76 {
77 STK_ASSERT(count != 0U); // API contract: number of parties cannot be 0
78 }
79
84
96 bool Wait() { return (WaitEx() == BARRIER_LAST_ARRIVAL); }
97
105 EResult WaitEx();
106
110 uint32_t GetThreshold() const { return m_threshold; }
111
112private:
114
117 const uint32_t m_threshold;
118 uint32_t m_count;
119 uint32_t m_generation;
120};
121
122// ---------------------------------------------------------------------------
123// WaitEx
124// ---------------------------------------------------------------------------
125
127{
128 EResult result = BARRIER_RELEASED;
129
130 STK_ASSERT(!hw::IsInsideISR()); // API contract: caller must not be in ISR
131
132 m_mutex.Lock();
133
134 const uint32_t gen = m_generation;
135
136 if (--m_count == 0U)
137 {
138 // last task to arrive: start a new generation and release everyone else
139 ++m_generation;
141
142 m_cond.NotifyAll();
143
144 result = BARRIER_LAST_ARRIVAL;
145 }
146 else
147 {
148 // wait in a loop to guard against spurious wakeups: keep waiting while
149 // we are still in the same generation we entered with
150 while (gen == m_generation)
151 {
153 {
154 // the cancel wakes this task before m_mutex is re-acquired, so the barrier may have
155 // tripped in between (the trip has then already consumed our arrival and reset
156 // m_count): signal wins, report a normal release and leave the count alone
157 if (gen == m_generation)
158 {
159 // bail out before the barrier tripped: undo our own arrival so the count
160 // stays consistent for whichever tasks remain in this generation - do NOT
161 // let the barrier trip short-handed on our behalf
162 ++m_count;
163 result = BARRIER_CANCELED;
164 }
165
166 break;
167 }
168 // else: WAIT_RESULT_SIGNAL - NotifyAll() always pairs with ++m_generation, so a
169 // genuine signal here means gen != m_generation already and the loop exits next check
170 }
171 }
172
173 m_mutex.Unlock();
174
175 return result;
176}
177
178} // namespace sync
179} // namespace stk
180
181#endif /* STK_SYNC_BARRIER_H_ */
#define STK_NONCOPYABLE_CLASS(TYPE)
Disables copy construction and assignment for a class.
Definition stk_defs.h:708
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:516
#define STK_VIRT_DTOR
Makes destructors virtual and compliant to strict rules if STK_STRICT_COMPLIANCY=0.
Definition stk_defs.h:261
Implementation of synchronization primitive: stk::sync::ConditionVariable.
Implementation of synchronization primitive: stk::sync::Mutex.
Namespace of STK package.
@ WAIT_RESULT_CANCELED
The wait was cancelled by another task via IKernel::CancelTaskWait(), independent of signal/timeout.
Definition stk_common.h:127
static constexpr Timeout WAIT_INFINITE
Timeout value: block indefinitely until the synchronization object is signaled.
Definition stk_common.h:214
bool IsInsideISR()
Check whether the CPU is currently executing inside a hardware interrupt service routine (ISR).
Synchronization primitives for task coordination and resource protection.
Traceable object.
Definition stk_common.h:533
uint32_t m_count
number of tasks still to arrive in the current generation
Barrier(uint32_t count)
Constructor.
uint32_t GetThreshold() const
Get the number of tasks required to trip the barrier.
ConditionVariable m_cond
signals waiting tasks when the current generation completes
uint32_t m_generation
generation counter, incremented every time the barrier trips
bool Wait()
Block the calling task until count tasks have called Wait().
EResult
Outcome of a Barrier::WaitEx() call.
@ BARRIER_LAST_ARRIVAL
This task was the last arrival and tripped the barrier.
@ BARRIER_RELEASED
Released because the barrier tripped; this task was not the last arrival.
const uint32_t m_threshold
number of tasks required to trip the barrier
Mutex m_mutex
protects m_count / m_generation and serializes calls to m_cond
EResult WaitEx()
Block the calling task until count tasks have called Wait(), preserving the full outcome.
Condition Variable primitive for signaling between tasks based on specific predicates.
Definition stk_sync_cv.h:68
Recursive mutex primitive that allows the same thread to acquire the lock multiple times.