SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_strategy_swrrobin.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_SWRROBIN_H_
11#define STK_STRATEGY_SWRROBIN_H_
12
17
18#include "stk_common.h"
19
20namespace stk {
21
63{
64public:
75
80
85
97 void AddTask(IKernelTask *task) override
98 {
99 STK_ASSERT(task != nullptr);
100 STK_ASSERT((task->GetWeight() > 0) && (task->GetWeight() <= 0x7FFFFF)); // must not be negative, max 24-bit number
101
103
104 AddActive(task);
105 }
106
115 void RemoveTask(IKernelTask *task) override
116 {
117 STK_ASSERT(task != nullptr);
118 STK_ASSERT((task->GetHead() == &m_tasks) || (task->GetHead() == &m_sleep));
119
120 if (task->GetHead() == &m_tasks)
121 {
122 RemoveActive(task);
123 }
124 else
125 {
126 m_sleep.Unlink(task);
127 }
128 }
129
143 {
144 IKernelTask *next = nullptr;
145
146 if (!m_tasks.IsEmpty())
147 {
148 IKernelTask *itr = (*m_tasks.GetFirst()), *const start = itr;
149 int32_t max_weight = INT32_MIN;
150
151 do
152 {
153 const int32_t candidate_weight = itr->GetCurrentWeight() + itr->GetWeight();
154 itr->SetCurrentWeight(candidate_weight);
155
156 if (candidate_weight > max_weight)
157 {
158 max_weight = candidate_weight;
159 next = itr;
160 }
161
162 itr = (*itr->GetNext());
163 }
164 while (itr != start);
165
166 STK_ASSERT(next != nullptr);
167
168 next->SetCurrentWeight(max_weight - m_total_weight);
169 }
170
171 return next;
172 }
173
181 {
182 STK_ASSERT(GetSize() != 0U);
183
184 return (*(!m_tasks.IsEmpty() ? m_tasks.GetFirst() : m_sleep.GetFirst()));
185 }
186
190 size_t GetSize() const override
191 {
192 return m_tasks.GetSize() + m_sleep.GetSize();
193 }
194
201 void OnTaskSleep(IKernelTask *task) override
202 {
203 STK_ASSERT(task != nullptr);
204 STK_ASSERT(task->IsSleeping());
205 STK_ASSERT(task->GetHead() == &m_tasks);
206
207 RemoveActive(task);
208 m_sleep.LinkBack(task);
209 }
210
223 void OnTaskWake(IKernelTask *task) override
224 {
225 STK_ASSERT(task != nullptr);
226 STK_ASSERT(!task->IsSleeping());
227 STK_ASSERT(task->GetHead() == &m_sleep);
228
229 m_sleep.Unlink(task);
230
231 // boost priority of the previously sleeping task, this resembles to a RR pattern
232 // with tasks having equal weights
234
235 AddActive(task);
236 }
237
238private:
240
247 {
248 m_tasks.LinkBack(task);
249 m_total_weight += task->GetWeight();
250 }
251
259 {
260 m_tasks.Unlink(task);
261 m_total_weight -= task->GetWeight();
262 }
263
267};
268
274
275} // namespace stk
276
277#endif /* STK_STRATEGY_SWRROBIN_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:516
#define STK_VIRT_DTOR
Makes destructors virtual and compliant to strict rules if STK_STRICT_COMPLIANCY=0.
Definition stk_defs.h:261
Namespace of STK package.
static constexpr Weight NO_WEIGHT
Weight value: weight is not set.
Definition stk_common.h:222
SwitchStrategySmoothWeightedRoundRobin SwitchStrategySWRR
Shorthand alias for SwitchStrategySmoothWeightedRoundRobin.
Scheduling-strategy-facing interface for a kernel task slot.
Definition stk_common.h:885
virtual Weight GetCurrentWeight() const =0
Get the current dynamic weight value of this task.
virtual Weight GetWeight() const =0
Get static base weight assigned to the task.
DLHeadType ListHeadType
List head type for IKernelTask elements.
Definition stk_common.h:890
virtual bool IsSleeping() const =0
Check whether the task is currently sleeping.
virtual void SetCurrentWeight(Weight weight)=0
Set the current dynamic weight value used by the scheduling strategy.
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.
Smooth Weighted Round-Robin (SWRR) task-switching strategy: distributes CPU time proportionally to pe...
STK_VIRT_DTOR ~SwitchStrategySmoothWeightedRoundRobin()=default
Destructor.
IKernelTask * GetFirst() override
Get first task in the managed set (used by the kernel for initial scheduling).
STK_NONCOPYABLE_CLASS(SwitchStrategySmoothWeightedRoundRobin)
void RemoveTask(IKernelTask *task) override
Remove task from whichever list it currently occupies.
SwitchStrategySmoothWeightedRoundRobin()
Construct an empty strategy with no tasks and a zero total weight.
void OnTaskWake(IKernelTask *task) override
Notification that a task has become runnable again.
void AddActive(IKernelTask *task)
Append task to m_tasks and update the total weight.
int32_t m_total_weight
Sum of static weights (GetWeight()) of all tasks currently in m_tasks. Sleeping tasks are excluded....
void OnTaskSleep(IKernelTask *task) override
Notification that a task has entered the sleeping state.
EConfig
Compile-time capability flags reported to the kernel.
@ PRIORITY_INHERITANCE_API
This strategy does not require Priority Inheritance and OnTaskPriorityChange() events.
@ SLEEP_EVENT_API
This strategy requires OnTaskSleep() / OnTaskWake() events to keep m_total_weight accurate as tasks m...
@ DEADLINE_MISSED_API
This strategy does not use OnTaskDeadlineMissed() events.
@ WEIGHT_API
This strategy uses per-task static and dynamic weights; the kernel must expose the Weight API on each...
IKernelTask * GetNext() override
Select and return the next task to run, applying one step of the SWRR algorithm.
void RemoveActive(IKernelTask *task)
Remove task from m_tasks and update the total weight.
size_t GetSize() const override
Get the total number of tasks managed by this strategy.
void AddTask(IKernelTask *task) override
Add task to the runnable set.
IKernelTask::ListHeadType m_tasks
Runnable tasks eligible for scheduling.
IKernelTask::ListHeadType m_sleep
Sleeping (blocked) tasks not eligible for scheduling.