SuperTinyKernel™ RTOS 1.06.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_strategy_rrobin.h
Go to the documentation of this file.
1/*
2 * SuperTinyKernel™ (STK): 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_RROBIN_H_
11#define STK_STRATEGY_RROBIN_H_
12
16
17#include "stk_common.h"
18
19namespace stk {
20
42{
43public:
54
59
64
72 void AddTask(IKernelTask *task) override
73 {
74 STK_ASSERT(task != nullptr);
75 STK_ASSERT(task->GetHead() == nullptr);
76
77 const bool tail = (m_prev == m_tasks.GetLast());
78
79 m_tasks.LinkBack(task);
80
81 // if pointer was pointing to the tail, become a tail
82 if (tail)
83 {
84 m_prev = task;
85 }
86 }
87
94 void RemoveTask(IKernelTask *task) override
95 {
96 STK_ASSERT(task != nullptr);
97 STK_ASSERT(GetSize() != 0);
98 STK_ASSERT((task->GetHead() == &m_tasks) || (task->GetHead() == &m_sleep));
99
100 if (task->GetHead() == &m_tasks)
101 {
102 RemoveActive(task);
103 }
104 else
105 {
106 m_sleep.Unlink(task);
107 }
108 }
109
120 {
121 IKernelTask *next = m_prev;
122
123 if (next != nullptr)
124 {
125 next = (*next->GetNext());
126 m_prev = next;
127 }
128
129 return next;
130 }
131
139 {
140 STK_ASSERT(GetSize() != 0U);
141
142 return (*(!m_tasks.IsEmpty() ? m_tasks.GetFirst() : m_sleep.GetFirst()));
143 }
144
148 size_t GetSize() const override
149 {
150 return m_tasks.GetSize() + m_sleep.GetSize();
151 }
152
158 void OnTaskSleep(IKernelTask *task) override
159 {
160 STK_ASSERT(task != nullptr);
161 STK_ASSERT(task->IsSleeping());
162 STK_ASSERT(task->GetHead() == &m_tasks);
163
164 RemoveActive(task);
165 m_sleep.LinkBack(task);
166 }
167
174 void OnTaskWake(IKernelTask *task) override
175 {
176 STK_ASSERT(task != nullptr);
177 STK_ASSERT(!task->IsSleeping());
178 STK_ASSERT(task->GetHead() == &m_sleep);
179
180 m_sleep.Unlink(task);
181 AddActive(task);
182 }
183
184protected:
186
194 {
195 m_tasks.LinkBack(task);
196
197 // update pointer: if all tasks were sleeping, this task will change state
198 // of the kernel to active
199 if (m_prev == nullptr)
200 {
201 m_prev = task;
202 }
203 }
204
218 {
219 IKernelTask *const next = (*task->GetNext());
220
221 m_tasks.Unlink(task);
222
223 // update pointer: set to previous task so that GetNext() could return next,
224 // if there are no tasks left GetNext() will return nullptr causing a sleep
225 // state for the kernel
226 if (next != task)
227 {
228 m_prev = (*next->GetPrev());
229 }
230 else
231 {
232 m_prev = nullptr;
233 }
234 }
235
239};
240
246
247} // namespace stk
248
249#endif /* STK_STRATEGY_RROBIN_H_ */
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:409
#define STK_VIRT_DTOR
Makes destructors virtual and compliant to strict rules if STK_STRICT_COMPLIANCY=0.
Definition stk_defs.h:159
Namespace of STK package.
SwitchStrategyRoundRobin SwitchStrategyRR
Shorthand alias for SwitchStrategyRoundRobin.
Scheduling-strategy-facing interface for a kernel task slot.
Definition stk_common.h:748
DLHeadType ListHeadType
List head type for IKernelTask elements.
Definition stk_common.h:753
virtual bool IsSleeping() const =0
Check whether the task is currently sleeping.
Interface for a task switching strategy implementation.
DLEntryType * GetNext()
Get the next entry in the list.
DLHeadType * GetHead()
Get the list head this entry currently belongs to.
DLEntryType * GetPrev()
Get the previous entry in the list.
Round-Robin task-switching strategy: each runnable task receives one time slice (one tick interval) i...
IKernelTask::ListHeadType m_tasks
Runnable tasks eligible for scheduling.
void RemoveActive(IKernelTask *task)
Remove a task from m_tasks and update the cursor.
void AddTask(IKernelTask *task) override
Add task to the runnable set.
void RemoveTask(IKernelTask *task) override
Remove task from whichever list it currently occupies.
void OnTaskWake(IKernelTask *task) override
Notification that a task has become runnable again.
IKernelTask::ListHeadType m_sleep
Sleeping (blocked) tasks not eligible for scheduling.
void OnTaskSleep(IKernelTask *task) override
Notification that a task has entered the sleeping state.
STK_VIRT_DTOR ~SwitchStrategyRoundRobin()=default
Destructor.
void AddActive(IKernelTask *task)
Append a task to m_tasks and restore the cursor if necessary.
SwitchStrategyRoundRobin()
Construct an empty strategy with no tasks and a null cursor.
EConfig
Compile-time capability flags reported to the kernel.
@ SLEEP_EVENT_API
This strategy requires OnTaskSleep() / OnTaskWake() events to maintain the active/sleep list split.
@ PRIORITY_INHERITANCE_API
This strategy does not require Priority Inheritance and OnTaskPriorityChange() events.
@ DEADLINE_MISSED_API
This strategy does not use OnTaskDeadlineMissed() events.
@ WEIGHT_API
This strategy does not use per-task weights; all tasks are treated equally.
IKernelTask * GetNext() override
Advance cursor and return the next runnable task.
size_t GetSize() const override
Get total number of tasks managed by this strategy.
IKernelTask * GetFirst() override
Get first task in the managed set (used by the kernel for initial scheduling).
STK_NONCOPYABLE_CLASS(SwitchStrategyRoundRobin)
IKernelTask * m_prev
Iterator cursor: the most recently scheduled task, or nullptr when no runnable tasks exist....