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::SwitchStrategyMonotonic< TStrategyType > Class Template Referencefinal

Monotonic scheduling strategy: Rate-Monotonic (RM) or Deadline-Monotonic (DM), selected at compile time by the TStrategyType template parameter. More...

#include <stk_strategy_monotonic.h>

Inheritance diagram for stk::SwitchStrategyMonotonic< TStrategyType >:
Collaboration diagram for stk::SwitchStrategyMonotonic< TStrategyType >:

Public Types

enum  EConfig {
  WEIGHT_API = 0 ,
  SLEEP_EVENT_API = 0 ,
  DEADLINE_MISSED_API = 0 ,
  PRIORITY_INHERITANCE_API = 0
}
 Compile-time capability flags reported to the kernel. More...

Public Member Functions

 SwitchStrategyMonotonic ()
 Construct an empty strategy with no tasks.
STK_VIRT_DTOR ~SwitchStrategyMonotonic ()=default
 Destructor.
void AddTask (IKernelTask *task) override
 Add a task to the priority-sorted runnable list.
void RemoveTask (IKernelTask *task) override
 Remove a task from the list.
IKernelTaskGetNext () override
 Select and return the highest-priority non-sleeping task.
IKernelTaskGetFirst () override
 Get the first task in the managed set (used by the kernel for initial scheduling).
size_t GetSize () const override
 Get the total number of tasks managed by this strategy.
void OnTaskSleep (IKernelTask *) override
 Not supported, asserts unconditionally.
void OnTaskWake (IKernelTask *) override
 Not supported, asserts unconditionally.
virtual bool OnTaskDeadlineMissed (IKernelTask *task)
 Notification that a task has exceeded its HRT deadline; returns whether the strategy can recover without a hard fault.
virtual void OnTaskWeightChange (IKernelTask *task, Weight old_weight)
 Notification that a runnable task's scheduling weight has changed.

Private Member Functions

 STK_NONCOPYABLE_CLASS (SwitchStrategyMonotonic)

Private Attributes

IKernelTask::ListHeadType m_tasks
 All tasks (runnable and sleeping) in priority order. GetNext() skips sleeping tasks via IsSleeping(). AddTask() maintains sort order.

Detailed Description

template<EMonotonicSwitchStrategyType TStrategyType>
class stk::SwitchStrategyMonotonic< TStrategyType >

Monotonic scheduling strategy: Rate-Monotonic (RM) or Deadline-Monotonic (DM), selected at compile time by the TStrategyType template parameter.

Template Parameters
TStrategyTypePolicy selector (EMonotonicSwitchStrategyType):
  • MSS_TYPE_RATE - Rate-Monotonic: tasks with a shorter scheduling period receive higher priority. The most frequently activating task always runs first.
  • MSS_TYPE_DEADLINE - Deadline-Monotonic: tasks with a shorter execution deadline receive higher priority.
Sorted-list design
m_tasks is maintained as a priority-sorted intrusive list. AddTask() inserts each new task at the correct sorted position (O(n) insertion sort) so that GetNext() need only scan from the front: the first non-sleeping task it encounters is always the highest-priority runnable task. No re-sorting occurs at runtime after a task is added.
Sleep handling - no separate sleep list
Unlike RR, SWRR, EDF, and FP strategies, this strategy does not maintain a separate sleep list (SLEEP_EVENT_API = 0). Sleeping tasks remain in m_tasks in their sorted position and are skipped by GetNext() via IKernelTask::IsSleeping(). OnTaskSleep() and OnTaskWake() assert unconditionally, the kernel must not be configured to deliver these events to this strategy.
HRT mode requirement
This strategy reads GetHrtPeriodicity() and GetHrtDeadline() from each task during AddTask() to determine its priority. These values are only populated in KERNEL_HRT mode; using this strategy without KERNEL_HRT produces undefined priority ordering.
Note
Does not use per-task weights (WEIGHT_API = 0). Priority is derived entirely from HRT timing parameters set via IKernel::AddTask(periodicity_tc, deadline_tc, ...).
For schedulability analysis of the configured task set use SchedulabilityCheck::IsSchedulableWCRT().
See also
SwitchStrategyRM, SwitchStrategyDM, SchedulabilityCheck, ITaskSwitchStrategy

Definition at line 69 of file stk_strategy_monotonic.h.

Member Enumeration Documentation

◆ EConfig

Compile-time capability flags reported to the kernel.

Enumerator
WEIGHT_API 

This strategy does not use per-task weights. Priority is derived from HRT timing parameters (GetHrtPeriodicity() for RM, GetHrtDeadline() for DM) at AddTask() time.

SLEEP_EVENT_API 

This strategy does not use OnTaskSleep() / OnTaskWake() events. Sleeping tasks remain in m_tasks and are skipped by GetNext() via IKernelTask::IsSleeping(). Delivering these events will trigger an assertion.

DEADLINE_MISSED_API 

This strategy does not use OnTaskDeadlineMissed() events.

PRIORITY_INHERITANCE_API 

This strategy does not require Priority Inheritance and OnTaskPriorityChange() events.

Definition at line 75 of file stk_strategy_monotonic.h.

76 {
77 WEIGHT_API = 0,
78 SLEEP_EVENT_API = 0,
81 };
@ DEADLINE_MISSED_API
This strategy does not use OnTaskDeadlineMissed() events.
@ WEIGHT_API
This strategy does not use per-task weights. Priority is derived from HRT timing parameters (GetHrtPe...
@ PRIORITY_INHERITANCE_API
This strategy does not require Priority Inheritance and OnTaskPriorityChange() events.
@ SLEEP_EVENT_API
This strategy does not use OnTaskSleep() / OnTaskWake() events. Sleeping tasks remain in m_tasks and ...

Constructor & Destructor Documentation

◆ SwitchStrategyMonotonic()

template<EMonotonicSwitchStrategyType TStrategyType>
stk::SwitchStrategyMonotonic< TStrategyType >::SwitchStrategyMonotonic ( )
inlineexplicit

Construct an empty strategy with no tasks.

Definition at line 85 of file stk_strategy_monotonic.h.

85 : m_tasks()
86 {}
IKernelTask::ListHeadType m_tasks
All tasks (runnable and sleeping) in priority order. GetNext() skips sleeping tasks via IsSleeping()....

◆ ~SwitchStrategyMonotonic()

Destructor.

Note
MISRA deviation: [STK-DEV-005] Rule 10-3-2.

Member Function Documentation

◆ AddTask()

template<EMonotonicSwitchStrategyType TStrategyType>
void stk::SwitchStrategyMonotonic< TStrategyType >::AddTask ( IKernelTask * task)
inlineoverridevirtual

Add a task to the priority-sorted runnable list.

Parameters
[in]taskTask to add. Must not be NULL and must not already be in any list.
Note
Performs an O(n) insertion sort into m_tasks so that higher-priority tasks appear closer to the head. The sort key depends on TStrategyType:
  • MSS_TYPE_RATE: key = GetHrtPeriodicity() (smaller -> nearer to head).
  • MSS_TYPE_DEADLINE: key = GetHrtDeadline() (smaller -> nearer to head).
Three insertion cases handled:
  1. Empty list: insert at front (LinkFront).
  2. New task has a strictly smaller key than the current head: insert at front (LinkFront), becoming the new highest-priority task.
  3. Otherwise: scan forward until a task with a larger-or-equal key is found, then insert immediately before it (Link), or append at back (LinkBack) if the scan reaches the end of the list.
Tasks with equal keys are ordered by registration time: later-added tasks go behind earlier-added tasks with the same key.

Implements stk::ITaskSwitchStrategy.

Definition at line 109 of file stk_strategy_monotonic.h.

110 {
111 STK_ASSERT(task != nullptr);
112 STK_ASSERT(task->GetHead() == nullptr);
113
114 if (m_tasks.IsEmpty())
115 {
116 m_tasks.LinkFront(task);
117 }
118 else
119 {
120 IKernelTask *itr = (*m_tasks.GetFirst()), *const start = itr;
121
122 for (;;)
123 {
124 bool higher_priority = false;
125 switch (TStrategyType)
126 {
127 case MSS_TYPE_RATE:
128 higher_priority = (task->GetHrtPeriodicity() < itr->GetHrtPeriodicity());
129 break;
131 higher_priority = (task->GetHrtDeadline() < itr->GetHrtDeadline());
132 break;
133 default:
134 STK_ASSERT(false);
135 break;
136 }
137
138 if (higher_priority)
139 {
140 if (itr == start)
141 {
142 m_tasks.LinkFront(task);
143 break;
144 }
145
146 m_tasks.Link(task, itr, itr->GetPrev());
147 break;
148 }
149
150 // end of the list
151 itr = (*itr->GetNext());
152 if (itr == start)
153 {
154 m_tasks.LinkBack(task);
155 break;
156 }
157 }
158 }
159 }
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:516
Monotonic scheduling strategy: Rate-Monotonic (RM) or Deadline-Monotonic (DM), selected at compile ti...
IKernelTask * GetNext() override
Select and return the highest-priority non-sleeping task.

◆ GetFirst()

template<EMonotonicSwitchStrategyType TStrategyType>
IKernelTask * stk::SwitchStrategyMonotonic< TStrategyType >::GetFirst ( )
inlineoverridevirtual

Get the first task in the managed set (used by the kernel for initial scheduling).

Returns
The first task in m_tasks (highest priority due to sort order). Asserts if m_tasks is empty.
Note
Because all tasks (runnable and sleeping) reside in m_tasks there is no sleep-list fallback path, unlike RR, SWRR, EDF, and FP strategies. The returned task may be sleeping; the kernel uses it only to seed the initial context before the first GetNext() call.

Implements stk::ITaskSwitchStrategy.

Definition at line 220 of file stk_strategy_monotonic.h.

221 {
222 STK_ASSERT(m_tasks.GetSize() != 0U);
223
224 return (*m_tasks.GetFirst());
225 }

◆ GetNext()

template<EMonotonicSwitchStrategyType TStrategyType>
IKernelTask * stk::SwitchStrategyMonotonic< TStrategyType >::GetNext ( )
inlineoverridevirtual

Select and return the highest-priority non-sleeping task.

Returns
The first non-sleeping task in m_tasks, or NULL if every task in the list is currently sleeping (kernel will sleep until the next activation).
Note
Because m_tasks is sorted in descending priority order by AddTask(), a linear scan from the head is sufficient: the first task for which IsSleeping() returns false is always the highest-priority runnable task. Complexity is O(k) where k is the number of sleeping tasks at the front of the list (i.e. higher-priority tasks currently between activations).

Implements stk::ITaskSwitchStrategy.

Definition at line 185 of file stk_strategy_monotonic.h.

186 {
187 IKernelTask *next = nullptr;
188
189 if (!m_tasks.IsEmpty())
190 {
191 IKernelTask *itr = (*m_tasks.GetFirst()), *const start = itr;
192
193 // scan from head (highest priority); skip tasks that are sleeping between
194 // periodic activations; return the first task ready to run
195 do
196 {
197 if (!itr->IsSleeping())
198 {
199 next = itr;
200 break; // list is sorted by priority; no need to continue
201 }
202
203 itr = (*itr->GetNext());
204 }
205 while (itr != start);
206 }
207
208 // nullptr means all tasks are sleeping, return idle signal to kernel
209 return next;
210 }

◆ GetSize()

template<EMonotonicSwitchStrategyType TStrategyType>
size_t stk::SwitchStrategyMonotonic< TStrategyType >::GetSize ( ) const
inlineoverridevirtual

Get the total number of tasks managed by this strategy.

Returns
Number of tasks in m_tasks. Includes both runnable and sleeping tasks since this strategy does not maintain a separate sleep list.

Implements stk::ITaskSwitchStrategy.

Definition at line 231 of file stk_strategy_monotonic.h.

232 {
233 return m_tasks.GetSize();
234 }

Referenced by stk::SwitchStrategyMonotonic< MSS_TYPE_RATE >::RemoveTask().

Here is the caller graph for this function:

◆ OnTaskDeadlineMissed()

virtual bool stk::ITaskSwitchStrategy::OnTaskDeadlineMissed ( IKernelTask * task)
inlinevirtualinherited

Notification that a task has exceeded its HRT deadline; returns whether the strategy can recover without a hard fault.

Parameters
[in]taskThe task whose deadline was missed. Must not be nullptr.
Returns
true — the strategy has absorbed the overrun (e.g. by escalating its scheduling mode): the kernel must not call HrtHardFailDeadline() for this tick. false — the strategy cannot recover: the kernel must call HrtHardFailDeadline() as normal.
Note
Budget Overrun API. Called by the kernel from UpdateTaskState() within a tick, after GetNext() has already been called for that tick. Only invoked when DEADLINE_MISSED_API == 1 in the concrete strategy's EConfig. Strategies that set DEADLINE_MISSED_API = 0 do not need to implement this method; the kernel will not call it and will proceed directly to HrtHardFailDeadline().
Returning true carries no implicit side-effects on task sleep state or duration counters — normal tick-driven scheduling remains responsible for those. This call only communicates "do not hard-fault this tick."
The base implementation returns false (unrecoverable), which is the correct default for strategies that do not implement overrun recovery.

Definition at line 1371 of file stk_common.h.

1372 {
1373 STK_UNUSED(task);
1374 return false;
1375 }
#define STK_UNUSED(X)
Explicitly marks a variable as unused to suppress compiler warnings.
Definition stk_defs.h:715

References STK_UNUSED.

◆ OnTaskSleep()

template<EMonotonicSwitchStrategyType TStrategyType>
void stk::SwitchStrategyMonotonic< TStrategyType >::OnTaskSleep ( IKernelTask * )
inlineoverridevirtual

Not supported, asserts unconditionally.

Note
This strategy uses SLEEP_EVENT_API = 0. Sleeping tasks remain in m_tasks in their sorted position and are detected by IsSleeping() in GetNext(). Calling this method indicates a kernel/strategy configuration mismatch.

Implements stk::ITaskSwitchStrategy.

Definition at line 241 of file stk_strategy_monotonic.h.

242 {
243 // Sleep API unsupported: RM/DM keeps a single sorted non-volatile list.
244 STK_ASSERT(false);
245 }

◆ OnTaskWake()

template<EMonotonicSwitchStrategyType TStrategyType>
void stk::SwitchStrategyMonotonic< TStrategyType >::OnTaskWake ( IKernelTask * )
inlineoverridevirtual

Not supported, asserts unconditionally.

Note
This strategy uses SLEEP_EVENT_API = 0. See OnTaskSleep() for rationale.

Implements stk::ITaskSwitchStrategy.

Definition at line 250 of file stk_strategy_monotonic.h.

251 {
252 // Sleep API unsupported: RM/DM keeps a single sorted non-volatile list.
253 STK_ASSERT(false);
254 }

◆ OnTaskWeightChange()

virtual void stk::ITaskSwitchStrategy::OnTaskWeightChange ( IKernelTask * task,
Weight old_weight )
inlinevirtualinherited

Notification that a runnable task's scheduling weight has changed.

Parameters
[in]taskThe task whose weight was just updated via SetWeight().
[in]old_weightThe previous weight of this task (required to remove it from the priority list belonging to that weight).
Note
Called only for tasks that are currently in the runnable set (not sleeping). The strategy must relink the task to reflect its new weight. For strategies with WEIGHT_API = 0 this is a no-op. For SwitchStrategyFixedPriority it moves the task from its old priority-level list to the new one and updates m_ready_bitmap.
Called from within a ScopedCriticalSection.

Reimplemented in stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >, and stk::SwitchStrategyFixedPriority< 32 >.

Definition at line 1389 of file stk_common.h.

1390 {
1391 STK_UNUSED(task);
1392 STK_UNUSED(old_weight);
1393 }

References STK_UNUSED.

◆ RemoveTask()

template<EMonotonicSwitchStrategyType TStrategyType>
void stk::SwitchStrategyMonotonic< TStrategyType >::RemoveTask ( IKernelTask * task)
inlineoverridevirtual

Remove a task from the list.

Parameters
[in]taskTask to remove. Must not be NULL. Must be in m_tasks (asserted).
Note
Unlike RR, SWRR, EDF, and FP strategies there is no separate sleep list: all tasks, runnable and sleeping, reside in m_tasks, so this method simply unlinks the task unconditionally without a list-membership check.

Implements stk::ITaskSwitchStrategy.

Definition at line 167 of file stk_strategy_monotonic.h.

168 {
169 STK_ASSERT(task != nullptr);
170 STK_ASSERT(GetSize() != 0U);
171 STK_ASSERT(task->GetHead() == &m_tasks);
172
173 m_tasks.Unlink(task);
174 }
size_t GetSize() const override
Get the total number of tasks managed by this strategy.

◆ STK_NONCOPYABLE_CLASS()

template<EMonotonicSwitchStrategyType TStrategyType>
stk::SwitchStrategyMonotonic< TStrategyType >::STK_NONCOPYABLE_CLASS ( SwitchStrategyMonotonic< TStrategyType > )
private

Member Data Documentation

◆ m_tasks

template<EMonotonicSwitchStrategyType TStrategyType>
IKernelTask::ListHeadType stk::SwitchStrategyMonotonic< TStrategyType >::m_tasks
private

All tasks (runnable and sleeping) in priority order. GetNext() skips sleeping tasks via IsSleeping(). AddTask() maintains sort order.

Definition at line 259 of file stk_strategy_monotonic.h.


The documentation for this class was generated from the following file: