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_semaphore.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_SEMAPHORE_H_
11#define STK_SYNC_SEMAPHORE_H_
12
13#include "stk_sync_cs.h"
14
18
19namespace stk {
20namespace sync {
21
55class Semaphore : public ITraceable, private ISyncObject
56{
57public:
61 explicit Semaphore(uint16_t initial_count = 0U, uint16_t max_count = 0xFFFEU)
62 : m_count(initial_count), m_count_max(max_count)
63 {
64 STK_ASSERT(initial_count < max_count); // API contract: initial count must not exceed maximum
65 }
66
74 {
75 STK_ASSERT(m_wait_list.IsEmpty()); // API contract: must not be destroyed with waiting tasks
76 }
77
83 bool Wait(Timeout timeout = WAIT_INFINITE);
84
92 bool TryWait() { return Wait(NO_WAIT); }
93
99 void Signal();
100
107 uint16_t GetCount() const { return m_count; }
108
109private:
111
112 uint16_t m_count;
113 uint16_t m_count_max;
114};
115
116// ---------------------------------------------------------------------------
117// Wait
118// ---------------------------------------------------------------------------
119
120inline bool Semaphore::Wait(Timeout timeout)
121{
123
124 // fast path: resource is available
125 if (m_count != 0U)
126 {
127 m_count = static_cast<uint16_t>(m_count - 1U);
128 __stk_full_memfence();
129 return true;
130 }
131
132 // try lock behavior (timeout=NO_WAIT)
133 if (timeout == NO_WAIT)
134 return false;
135
136 STK_ASSERT(!hw::IsInsideISR()); // API contract: caller must not be in ISR if timeout!=NO_WAIT
137
138 // slow path: block until Signal() or timeout
139 // note: after waking, if not a timeout, we effectively own the resource that Signal() produced
140 // but didn't put into m_count (see logic of if (m_wait_list.IsEmpty()) in Signal())
141 return !IKernelService::GetInstance()->Wait(this, &cs_, timeout)->IsTimeout();
142}
143
144// ---------------------------------------------------------------------------
145// Signal
146// ---------------------------------------------------------------------------
147
148inline void Semaphore::Signal()
149{
151
152 if (m_wait_list.IsEmpty())
153 {
154 STK_ASSERT(m_count < m_count_max); // API contract: the count must not exceed maximum
155
156 // no one is waiting, save signal for later
157 m_count = static_cast<uint16_t>(m_count + 1U);
158 __stk_full_memfence();
159 }
160 else
161 {
162 // give signal directly to the first waiting task
163 WakeOne();
164 }
165}
166
167} // namespace sync
168} // namespace stk
169
170#endif /* STK_SYNC_SEMAPHORE_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.
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
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
void Signal()
Post a signal (increment counter).
uint16_t m_count_max
Counter max limit.
STK_NONCOPYABLE_CLASS(Semaphore)
Semaphore(uint16_t initial_count=0U, uint16_t max_count=0xFFFEU)
Constructor.
uint16_t m_count
Internal resource counter.
bool Wait(Timeout timeout=WAIT_INFINITE)
Wait for a signal (decrement counter).
uint16_t GetCount() const
Get current counter value.
bool TryWait()
Poll the semaphore without blocking (decrement counter if available).