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_strategy_fpriority.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_STRATEGY_FPRIORITY_H_
11#define STK_STRATEGY_FPRIORITY_H_
12
17
18#include "stk_common.h"
19
20namespace stk {
21
57template <uint8_t MAX_PRIORITIES>
59{
60public:
70
77 {
78 PRIORITY_HIGHEST = MAX_PRIORITIES - 1,
79 PRIORITY_NORMAL = MAX_PRIORITIES / 2,
81 };
82
88 {
89 STK_STATIC_ASSERT_DESC(MAX_PRIORITIES <= 32U,
90 "MAX_PRIORITIES exceeds 32-bit bitmap width");
91 }
92
98
112 {
113 STK_ASSERT(task != nullptr);
114 STK_ASSERT(task->GetHead() == nullptr);
115 STK_ASSERT(GetTaskPriority(task) < MAX_PRIORITIES);
116
117 const Priority prio = GetTaskPriority(task);
118
119 bool is_tail = (m_prev[prio] == m_tasks[prio].GetLast());
120
121 AddActive(task);
122
123 // if pointer was pointing to the tail, become a tail
124 if (is_tail)
125 m_prev[prio] = task;
126 }
127
137 {
138 STK_ASSERT(task != nullptr);
139 STK_ASSERT(GetSize() != 0U);
140 STK_ASSERT((task->GetHead() == &m_tasks[GetTaskPriority(task)]) || (task->GetHead() == &m_sleep));
141
142 if (task->GetHead() == &m_sleep)
143 m_sleep.Unlink(task);
144 else
145 RemoveActive(task);
146 }
147
158 {
159 if (m_ready_bitmap == 0U)
160 return nullptr; // idle
161
163
164 IKernelTask *ret = (*m_prev[prio]->GetNext());
165 m_prev[prio] = ret;
166
167 return ret;
168 }
169
179 {
180 STK_ASSERT(GetSize() != 0U);
181
182 if (m_ready_bitmap == 0U)
183 return (*m_sleep.GetFirst());
184
186 return (*m_tasks[prio].GetFirst());
187 }
188
194 size_t GetSize() const
195 {
196 size_t total = m_sleep.GetSize();
197 for (Priority i = 0U; i < MAX_PRIORITIES; i += 1U)
198 total += m_tasks[i].GetSize();
199
200 return total;
201 }
202
210 {
211 STK_ASSERT(task != nullptr);
212 STK_ASSERT(task->IsSleeping());
213 STK_ASSERT(task->GetHead() == &m_tasks[GetTaskPriority(task)]);
214
215 RemoveActive(task);
216 m_sleep.LinkBack(task);
217 }
218
229 {
230 STK_ASSERT(task != nullptr);
231 STK_ASSERT(!task->IsSleeping());
232 STK_ASSERT(task->GetHead() == &m_sleep);
233
234 m_sleep.Unlink(task);
235 AddActive(task);
236 }
237
242 {
243 // Budget Overrun API unsupported
244 STK_ASSERT(false);
245 return false;
246 }
247
248protected:
250 typedef uint8_t Priority;
251
262 {
263 const Priority prio = GetTaskPriority(task);
264
265 m_tasks[prio].LinkBack(task);
266
267 // init pointer
268 if (m_tasks[prio].GetSize() == 1U)
269 {
270 m_prev[prio] = task;
271
272 m_ready_bitmap |= (1U << prio);
273 }
274 }
275
289 {
290 const Priority prio = GetTaskPriority(task);
291 IKernelTask *next = (*task->GetNext());
292
293 m_tasks[prio].Unlink(task);
294
295 // update pointer
296 if (next != task)
297 {
298 m_prev[prio] = (*next->GetPrev());
299 }
300 else
301 {
302 m_prev[prio] = nullptr;
303
304 // this will cause a switch to a lower priority task list
305 m_ready_bitmap &= ~(1U << prio);
306 }
307 }
308
314 {
315 return static_cast<Priority>(task->GetWeight());
316 }
317
328 {
329 #if defined(__GNUC__)
330 return static_cast<Priority>(31U - __builtin_clz(bitmap));
331 #else
332 for (int8_t i = 31; i >= 0; --i)
333 {
334 if (bitmap & (1U << i))
335 return static_cast<Priority>(i);
336 }
337 return 0;
338 #endif
339 }
340
341private:
343
346 uint32_t m_ready_bitmap;
347 IKernelTask *m_prev[MAX_PRIORITIES];
348};
349
356
357} // namespace stk
358
359#endif /* STK_STRATEGY_FPRIORITY_H_ */
Contains interface definitions of the library.
#define __stk_forceinline
Forces compiler to always inline the decorated function, regardless of optimisation level.
Definition stk_defs.h:104
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:330
#define STK_STATIC_ASSERT_DESC(X, DESC)
Compile-time assertion with a custom error description. Produces a compilation error if X is false.
Definition stk_defs.h:350
Namespace of STK package.
SwitchStrategyFixedPriority< 32 > SwitchStrategyFP32
Shorthand alias for SwitchStrategyFixedPriority<32>: 32 priority levels (0..31), using a single 32-bi...
Scheduling-strategy-facing interface for a kernel task slot.
Definition stk_common.h:493
DLHeadType ListHeadType
List head type for IKernelTask elements.
Definition stk_common.h:498
virtual bool IsSleeping() const =0
Check whether the task is currently sleeping.
virtual int32_t GetWeight() const =0
Get static base weight assigned to the task.
Interface for a task switching strategy implementation.
Definition stk_common.h:782
DLEntryType * GetPrev() const
Get the previous entry in the list.
DLHeadType * GetHead() const
Get the list head this entry currently belongs to.
DLEntryType * GetNext() const
Get the next entry in the list.
Fixed-priority preemptive scheduling strategy with round-robin arbitration within each priority level...
void AddTask(IKernelTask *task)
Add task to the runnable set at its fixed priority level.
SwitchStrategyFixedPriority()
Construct an empty strategy with all priority levels empty, a clear bitmap, and null cursors.
void AddActive(IKernelTask *task)
Append a task to its priority level's runnable list and update the bitmap.
IKernelTask * GetFirst() const
Get the first task in the managed set (used by the kernel for initial scheduling).
static __stk_forceinline Priority GetTaskPriority(IKernelTask *task)
Get priority from the task..
STK_NONCOPYABLE_CLASS(SwitchStrategyFixedPriority)
bool OnTaskDeadlineMissed(IKernelTask *)
Not supported, asserts unconditionally.
void RemoveTask(IKernelTask *task)
Remove task from whichever list it currently occupies.
EPriority
Symbolic priority level constants for common use cases.
void OnTaskSleep(IKernelTask *task)
Notification that a task has entered the sleeping state.
void RemoveActive(IKernelTask *task)
Remove a task from its priority level's runnable list and update the bitmap/cursor.
static __stk_forceinline Priority GetHighestReadyPriority(uint32_t bitmap)
Find the index of the highest set bit in bitmap.
size_t GetSize() const
Get the total number of tasks managed by this strategy.
IKernelTask * GetNext()
Select and return the next task to run.
void OnTaskWake(IKernelTask *task)
Notification that a task has become runnable again.
EConfig
Compile-time capability flags reported to the kernel.
IKernelTask::ListHeadType m_tasks[MAX_PRIORITIES]