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_spinlock.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_SPINLOCK_H_
11#define STK_SYNC_SPINLOCK_H_
12
13#include "stk_common.h"
14
18
19namespace stk {
20namespace sync {
21
53class SpinLock : public IMutex
54{
55public:
60
67 {
68 STK_ASSERT(m_owner_tid == TID_NONE); // API contract: lock must not be destroyed while held
69 }
70
77 void Lock();
78
84 bool TryLock();
85
92 void Unlock();
93
94private:
96
97 bool LockRecursively(TId locking_tid);
98 void MakeLocked(TId locking_tid);
99
100 static const uint16_t RECURSION_MAX = 0xFFFEU;
101
105};
106
107// ---------------------------------------------------------------------------
108// Lock
109// ---------------------------------------------------------------------------
110
111inline void SpinLock::Lock()
112{
113 TId current_tid = GetTid();
114
115 // increase recursion if this thread already owns the lock
116 if (!LockRecursively(current_tid))
117 {
118 m_lock.Lock();
119 MakeLocked(current_tid);
120 }
121}
122
123// ---------------------------------------------------------------------------
124// TryLock
125// ---------------------------------------------------------------------------
126
127inline bool SpinLock::TryLock()
128{
129 TId current_tid = GetTid();
130
131 // increase recursion if this thread already owns the lock
132 if (!LockRecursively(current_tid))
133 {
134 if (!m_lock.TryLock())
135 return false;
136
137 MakeLocked(current_tid);
138 }
139
140 return true;
141}
142
143// ---------------------------------------------------------------------------
144// Unlock
145// ---------------------------------------------------------------------------
146
147inline void SpinLock::Unlock()
148{
149 STK_ASSERT(!hw::IsInsideISR()); // API contract: caller must not be in ISR
150 STK_ASSERT(m_owner_tid == GetTid()); // API contract: caller must own the lock
151 STK_ASSERT(m_recursion_count != 0U); // API contract: must have matching Lock()
152
153 if (--m_recursion_count == 0U)
154 {
156 __stk_full_memfence();
157
158 m_lock.Unlock();
159 }
160}
161
162// ---------------------------------------------------------------------------
163// LockRecursively
164// ---------------------------------------------------------------------------
165
166inline bool SpinLock::LockRecursively(TId locking_tid)
167{
168 if ((m_owner_tid == locking_tid) && (m_recursion_count != 0U))
169 {
170 STK_ASSERT(m_recursion_count < RECURSION_MAX); // API contract: caller must not exceed max recursion depth
171
173 return true;
174 }
175
176 return false;
177}
178
179// ---------------------------------------------------------------------------
180// MakeLocked
181// ---------------------------------------------------------------------------
182
183inline void SpinLock::MakeLocked(TId locking_tid)
184{
185 // kernel invariant: if either condition is false, the low-level lock and the
186 // recursion counter are out of sync, this is an internal defect, not a caller error
187 if ((m_owner_tid != TID_NONE) || (m_recursion_count != 0U))
189
190 m_owner_tid = locking_tid;
192 __stk_full_memfence();
193}
194
195} // namespace sync
196} // namespace stk
197
198#endif /* STK_SYNC_SPINLOCK_H_ */
#define STK_KERNEL_PANIC(id)
Called when the kernel detects an unrecoverable internal fault.
Definition stk_arch.h:63
Contains interface definitions of the library.
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:330
Namespace of STK package.
TId GetTid()
Get task/thread Id of the calling task.
Definition stk_helper.h:217
Word TId
Definition stk_common.h:117
const TId TID_NONE
Reserved task/thread id representing zero/none thread id.
Definition stk_common.h:128
@ KERNEL_PANIC_ASSERT
Internal assertion failed (maps from STK_ASSERT).
Definition stk_common.h:56
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.
Atomic busy-wait lock used as the global cross-core synchronisation primitive inside CriticalSection.
Definition stk_arch.h:275
Interface for mutex synchronization primitive.
Definition stk_common.h:381
static const uint16_t RECURSION_MAX
maximum nesting depth
STK_NONCOPYABLE_CLASS(SpinLock)
void Unlock()
Release the lock or decrement the recursion counter.
uint16_t m_recursion_count
nesting depth
hw::SpinLock m_lock
low-level spin lock
bool LockRecursively(TId locking_tid)
TId m_owner_tid
thread id of the current owner
bool TryLock()
Attempt to acquire the lock without blocking.
void MakeLocked(TId locking_tid)
void Lock()
Acquire the lock.
SpinLock()
Construct a SpinLock in the unlocked state.