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_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:
74
79
85
97 void AddTask(IKernelTask *task)
98 {
99 STK_ASSERT(task != nullptr);
100
101 STK_ASSERT((task->GetWeight() > 0) && (task->GetWeight() <= 0x7FFFFF)); // must not be negative, max 24-bit number
102
103 task->SetCurrentWeight(0);
104
105 AddActive(task);
106 }
107
117 {
118 STK_ASSERT(task != nullptr);
119 STK_ASSERT(task->GetHead() == &m_tasks || task->GetHead() == &m_sleep);
120
121 if (task->GetHead() == &m_tasks)
122 RemoveActive(task);
123 else
124 m_sleep.Unlink(task);
125 }
126
140 {
141 if (m_tasks.IsEmpty())
142 return nullptr; // idle
143
144 IKernelTask *selected = nullptr;
145 int32_t max_weight = INT32_MIN;
146 IKernelTask *itr = (*m_tasks.GetFirst()), * const start = itr;
147
148 do
149 {
150 const int32_t candidate_weight = itr->GetCurrentWeight() + itr->GetWeight();
151 itr->SetCurrentWeight(candidate_weight);
152
153 if (candidate_weight > max_weight)
154 {
155 max_weight = candidate_weight;
156 selected = itr;
157 }
158 }
159 while ((itr = (*itr->GetNext())) != start);
160
161 STK_ASSERT(selected != nullptr);
162
163 selected->SetCurrentWeight(max_weight - m_total_weight);
164
165 return selected;
166 }
167
175 {
176 STK_ASSERT(GetSize() != 0U);
177
178 if (!m_tasks.IsEmpty())
179 return (*m_tasks.GetFirst());
180 else
181 return (*m_sleep.GetFirst());
182 }
183
187 size_t GetSize() const
188 {
189 return m_tasks.GetSize() + m_sleep.GetSize();
190 }
191
199 {
200 STK_ASSERT(task != nullptr);
201 STK_ASSERT(task->IsSleeping());
202 STK_ASSERT(task->GetHead() == &m_tasks);
203
204 RemoveActive(task);
205 m_sleep.LinkBack(task);
206 }
207
221 {
222 STK_ASSERT(task != nullptr);
223 STK_ASSERT(!task->IsSleeping());
224 STK_ASSERT(task->GetHead() == &m_sleep);
225
226 m_sleep.Unlink(task);
227
228 // boost priority of the previously sleeping task, this resembles to a RR pattern
229 // with tasks having equal weights
231
232 AddActive(task);
233 }
234
239 {
240 // Budget Overrun API unsupported
241 STK_ASSERT(false);
242 return false;
243 }
244
245private:
247
254 {
255 m_tasks.LinkBack(task);
256 m_total_weight += task->GetWeight();
257 }
258
266 {
267 m_tasks.Unlink(task);
268 m_total_weight -= task->GetWeight();
269 }
270
274};
275
281
282} // namespace stk
283
284#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:330
Namespace of STK package.
SwitchStrategySmoothWeightedRoundRobin SwitchStrategySWRR
Shorthand alias for SwitchStrategySmoothWeightedRoundRobin.
Scheduling-strategy-facing interface for a kernel task slot.
Definition stk_common.h:493
virtual int32_t GetCurrentWeight() const =0
Get the current dynamic weight value of this task.
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 void SetCurrentWeight(int32_t weight)=0
Set the current dynamic weight value used by the scheduling strategy.
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
DLHeadType * GetHead() const
Get the list head this entry currently belongs to.
DLEntryType * GetNext() const
Get the next entry in the list.
Smooth Weighted Round-Robin (SWRR) task-switching strategy: distributes CPU time proportionally to pe...
STK_NONCOPYABLE_CLASS(SwitchStrategySmoothWeightedRoundRobin)
bool OnTaskDeadlineMissed(IKernelTask *)
Not supported, asserts unconditionally.
size_t GetSize() const
Get the total number of tasks managed by this strategy.
SwitchStrategySmoothWeightedRoundRobin()
Construct an empty strategy with no tasks and a zero total weight.
IKernelTask * GetFirst() const
Get first task in the managed set (used by the kernel for initial scheduling).
void AddActive(IKernelTask *task)
Append task to m_tasks and update the total weight.
IKernelTask * GetNext()
Select and return the next task to run, applying one step of the SWRR algorithm.
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)
Notification that a task has entered the sleeping state.
void OnTaskWake(IKernelTask *task)
Notification that a task has become runnable again.
EConfig
Compile-time capability flags reported to the kernel.
@ 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...
void RemoveActive(IKernelTask *task)
Remove task from m_tasks and update the total weight.
void RemoveTask(IKernelTask *task)
Remove task from whichever list it currently occupies.
void AddTask(IKernelTask *task)
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.