SuperTinyKernel™ RTOS 1.05.3
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_sync_event.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_EVENT_H_
11#define STK_SYNC_EVENT_H_
12
13#include "stk_sync_cs.h"
14
18
19namespace stk {
20namespace sync {
21
61class Event : public ITraceable, private ISyncObject
62{
63public:
69 explicit Event(bool manual_reset = false, bool initial_state = false)
70 : m_manual_reset(manual_reset), m_signaled(initial_state)
71 {}
72
79 {
80 STK_ASSERT(m_wait_list.IsEmpty()); // API contract: must not be destroyed with waiting tasks
81 }
82
94 bool Set();
95
103 bool Reset();
104
111 bool Wait(Timeout timeout = WAIT_INFINITE);
112
121 bool TryWait();
122
132 void Pulse();
133
134private:
136
137 void RemoveWaitObject(IWaitObject *wobj);
138
141};
142
143// ---------------------------------------------------------------------------
144// Set
145// ---------------------------------------------------------------------------
146
147inline bool Event::Set()
148{
150
151 if (m_signaled)
152 return false;
153
154 m_signaled = true;
155 __stk_full_memfence();
156
157 if (m_manual_reset)
158 WakeAll();
159 else
160 WakeOne(); // auto-reset is applied in RemoveWaitObject when the waiter is removed
161
162 return true;
163}
164
165// ---------------------------------------------------------------------------
166// Reset
167// ---------------------------------------------------------------------------
168
169inline bool Event::Reset()
170{
172
173 bool prev = m_signaled;
174
175 m_signaled = false;
176 __stk_full_memfence();
177
178 return prev;
179}
180
181// ---------------------------------------------------------------------------
182// Pulse
183// ---------------------------------------------------------------------------
184
185inline void Event::Pulse()
186{
188
189 // transition to signaled so that WakeOne/WakeAll can release waiters:
190 // m_signaled is only visible as true while this critical section is held —
191 // any woken task will have the event auto-reset in RemoveWaitObject before
192 // it can observe m_signaled via Wait() or TryWait()
193 m_signaled = true;
194 __stk_full_memfence();
195
196 if (!m_wait_list.IsEmpty())
197 {
198 if (m_manual_reset)
199 WakeAll();
200 else
201 WakeOne(); // auto-reset applied in RemoveWaitObject
202 }
203
204 // force return to non-signaled regardless of whether anyone was waiting
205 m_signaled = false;
206 __stk_full_memfence();
207}
208
209// ---------------------------------------------------------------------------
210// Wait
211// ---------------------------------------------------------------------------
212
213inline bool Event::Wait(Timeout timeout)
214{
215 STK_ASSERT(!hw::IsInsideISR()); // API contract: caller must not be in ISR
216
218
219 // fast path: already signaled
220 if (m_signaled)
221 {
222 if (!m_manual_reset)
223 {
224 m_signaled = false;
225 __stk_full_memfence();
226 }
227
228 return true;
229 }
230
231 // non-blocking poll: event not signaled, return immediately
232 if (timeout == NO_WAIT)
233 return false;
234
235 // slow path: block until Set() signals the event or timeout expires
236 return !IKernelService::GetInstance()->Wait(this, &cs_, timeout)->IsTimeout();
237}
238
239// ---------------------------------------------------------------------------
240// TryWait
241// ---------------------------------------------------------------------------
242
243inline bool Event::TryWait()
244{
246
247 if (m_signaled)
248 {
249 if (!m_manual_reset)
250 {
251 m_signaled = false;
252 __stk_full_memfence();
253 }
254
255 return true;
256 }
257
258 return false;
259}
260
261// ---------------------------------------------------------------------------
262// RemoveWaitObject
263// ---------------------------------------------------------------------------
264
266{
268
269 // kernel invariant: auto-reset is applied here, not at the Set()/Pulse() call site,
270 // when a task wakes due to a signal (not a timeout), the event transitions back to
271 // non-signaled so that subsequent Wait() calls block until the next Set().
272 if (!m_manual_reset && m_signaled && !wobj->IsTimeout())
273 {
274 m_signaled = false;
275 __stk_full_memfence();
276 }
277}
278
279} // namespace sync
280} // namespace stk
281
282#endif /* STK_SYNC_EVENT_H_ */
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:330
Implementation of synchronization primitive: stk::sync::ScopedCriticalSection.
Namespace of STK package.
const Timeout WAIT_INFINITE
Timeout value: block indefinitely until the synchronization object is signaled.
Definition stk_common.h:139
int32_t Timeout
Timeout time (ticks).
Definition stk_common.h:133
const Timeout NO_WAIT
Timeout value: return immediately if the synchronization object is not yet signaled (non-blocking pol...
Definition stk_common.h:145
bool IsInsideISR()
Check whether the CPU is currently executing inside a hardware interrupt service routine (ISR).
Definition stktest.cpp:103
Synchronization primitives for task coordination and resource protection.
Wait object.
Definition stk_common.h:212
virtual bool IsTimeout() const =0
Check if task woke up due to a timeout.
Traceable object.
Definition stk_common.h:255
IWaitObject::ListHeadType m_wait_list
tasks blocked on this object
Definition stk_common.h:373
void WakeOne()
Wake the first task in the wait list (FIFO order).
Definition stk_common.h:357
ISyncObject()
Constructor.
Definition stk_common.h:350
void WakeAll()
Wake all tasks currently in the wait list.
Definition stk_common.h:367
virtual void RemoveWaitObject(IWaitObject *wobj)
Called by kernel when a waiting task is being removed (timeout expired, wait aborted,...
Definition stk_common.h:327
static IKernelService * GetInstance()
Get CPU-local instance of the kernel service.
Definition stktest.cpp:69
virtual IWaitObject * Wait(ISyncObject *sobj, IMutex *mutex, Timeout timeout)=0
Put calling process into a waiting state until synchronization object is signaled or timeout occurs.
RAII-style low-level synchronization primitive for atomic code execution. Used as building brick for ...
Definition stk_sync_cs.h:54
~Event()
Destructor.
bool Set()
Set event to signaled state.
void Pulse()
Pulse event: attempt to release waiters and then reset (Win32 PulseEvent() semantics).
bool TryWait()
Poll event state without blocking.
STK_NONCOPYABLE_CLASS(Event)
bool Reset()
Reset event to non-signaled state.
bool m_signaled
current signaled state of the event
void RemoveWaitObject(IWaitObject *wobj)
Called by kernel when a waiting task is being removed (timeout expired, wait aborted,...
Event(bool manual_reset=false, bool initial_state=false)
Constructor.
bool Wait(Timeout timeout=WAIT_INFINITE)
Wait until event becomes signaled or the timeout expires.
bool m_manual_reset
true = manual-reset event, false = auto-reset