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::SwitchStrategyFixedPriority< MAX_PRIORITIES > Class Template Referencefinal

Fixed-priority preemptive scheduling strategy with round-robin arbitration within each priority level. More...

#include <stk_strategy_fpriority.h>

Inheritance diagram for stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >:
Collaboration diagram for stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >:

Public Types

enum  EConfig {
  WEIGHT_API = 1 ,
  SLEEP_EVENT_API = 1 ,
  DEADLINE_MISSED_API = 0 ,
  PRIORITY_INHERITANCE_API = 1
}
 Compile-time capability flags reported to the kernel. More...
enum  EPriority {
  PRIORITY_HIGHEST = (MAX_PRIORITIES - 1) ,
  PRIORITY_HIGH = ((MAX_PRIORITIES / 2) + (MAX_PRIORITIES - 1)) / 2 ,
  PRIORITY_ABOVE_NORMAL = (MAX_PRIORITIES / 2) + 1 ,
  PRIORITY_NORMAL = (MAX_PRIORITIES / 2) ,
  PRIORITY_BELOW_NORMAL = (MAX_PRIORITIES / 2) - 1 ,
  PRIORITY_LOWER = (MAX_PRIORITIES / 4) ,
  PRIORITY_ABOVE_LOWEST = (0 + 1) ,
  PRIORITY_LOWEST = 0
}
 Symbolic priority level constants for common use cases. More...

Public Member Functions

 SwitchStrategyFixedPriority ()
 Construct an empty strategy with all priority levels empty, a clear bitmap, and null cursors.
STK_VIRT_DTOR ~SwitchStrategyFixedPriority ()=default
 Destructor.
void AddTask (IKernelTask *task) override
 Add task to the runnable set at its fixed priority level.
void RemoveTask (IKernelTask *task) override
 Remove task from whichever list it currently occupies.
IKernelTaskGetNext () override
 Select and return the next task to run.
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 *task) override
 Notification that a task has entered the sleeping state.
void OnTaskWake (IKernelTask *task) override
 Notification that a task has become runnable again.
void OnTaskWeightChange (IKernelTask *task, Weight old_weight) override
 Move a runnable task to a new priority level after its weight changed.
virtual bool OnTaskDeadlineMissed (IKernelTask *task)
 Notification that a task has exceeded its HRT deadline; returns whether the strategy can recover without a hard fault.

Protected Types

typedef uint8_t Priority
 Priority type.

Protected Member Functions

void AddActive (IKernelTask *task)
 Append a task to its priority level's runnable list and update the bitmap.
void RemoveActive (IKernelTask *task, const Priority prio)
 Remove a task from its priority level's runnable list and update the bitmap/cursor.

Static Protected Member Functions

static __stk_forceinline Priority GetTaskPriorityFromWeight (int32_t weight)
 Get priority from the task.
static __stk_forceinline Priority GetTaskPriority (IKernelTask *task)
 Get priority from the task.
static __stk_forceinline Priority GetHighestReadyPriority (uint32_t bitmap)
 Find the index of the highest set bit in bitmap.

Private Member Functions

 STK_NONCOPYABLE_CLASS (SwitchStrategyFixedPriority)

Private Attributes

IKernelTask::ListHeadType m_tasks [MAX_PRIORITIES]
 Per-priority runnable task lists. m_tasks[i] holds all runnable tasks at priority level i.
IKernelTask::ListHeadType m_sleep
 Sleeping (blocked) tasks. Priority is retained in GetWeight() and restored on OnTaskWake().
uint32_t m_ready_bitmap
 Bitmask of non-empty priority levels: bit i is set when m_tasks[i] has at least one runnable task. Updated by AddActive() (bit set) and RemoveActive() (bit cleared on last removal).
IKernelTaskm_prev [MAX_PRIORITIES]
 Per-priority round-robin cursor. m_prev[i] is the most recently scheduled task at level i, or nullptr when level i is empty. GetNext() advances from this position.

Detailed Description

template<uint8_t MAX_PRIORITIES>
class stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >

Fixed-priority preemptive scheduling strategy with round-robin arbitration within each priority level.

Template Parameters
MAX_PRIORITIESNumber of distinct priority levels. Must be in the range [1, 32] (enforced by a compile-time assertion). Bit i of the 32-bit m_ready_bitmap represents priority level i. The concrete alias SwitchStrategyFP32 uses MAX_PRIORITIES = 32.
Priority assignment
Each task's priority is read from ITask::GetWeight(), cast to uint8_t, and must be in the range [0, MAX_PRIORITIES - 1]. Tasks do not use the dynamic current-weight mechanism, the static weight value is the priority. Configure a task's priority by overriding ITask::GetWeight() to return the desired level.
Scheduling rules
  • The highest runnable priority level is always selected. A task at priority N will never run while any task at priority > N is runnable.
  • Tasks at the same priority level are scheduled in round-robin order (one tick slice each), using a per-level cursor (m_prev[prio]).
  • Higher numeric value = higher priority. 0 is the lowest, MAX_PRIORITIES - 1 is highest.
Priority detection — O(1) bitmap
m_ready_bitmap is a 32-bit bitmask where bit i is set whenever priority level i has at least one runnable task. GetNext() and GetFirst() locate the highest set bit in O(1) via __builtin_clz (GCC/Clang) or a portable 32->0 scan fallback. The bitmap is kept consistent by AddActive() (bit set) and RemoveActive() (bit cleared on last removal).
Note
Uses the Weight API (WEIGHT_API = 1): GetWeight() is interpreted as the task's fixed priority level. The dynamic weight functions (SetCurrentWeight / GetCurrentWeight) are not used by this strategy.
Requires the kernel Sleep API (SLEEP_EVENT_API = 1): OnTaskSleep() and OnTaskWake() maintain the per-priority runnable lists and keep m_ready_bitmap accurate.
See also
SwitchStrategyFP32, ITaskSwitchStrategy, ITask::GetWeight

Definition at line 58 of file stk_strategy_fpriority.h.

Member Typedef Documentation

◆ Priority

template<uint8_t MAX_PRIORITIES>
typedef uint8_t stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::Priority
protected

Priority type.

Definition at line 291 of file stk_strategy_fpriority.h.

Member Enumeration Documentation

◆ EConfig

template<uint8_t MAX_PRIORITIES>
enum stk::SwitchStrategyFixedPriority::EConfig

Compile-time capability flags reported to the kernel.

Enumerator
WEIGHT_API 

This strategy interprets GetWeight() as the task's fixed priority level (0 .. MAX_PRIORITIES - 1). Dynamic weight functions are not used.

SLEEP_EVENT_API 

This strategy requires OnTaskSleep() / OnTaskWake() events to maintain per-priority runnable lists and keep m_ready_bitmap accurate.

DEADLINE_MISSED_API 

This strategy does not use OnTaskDeadlineMissed() events.

PRIORITY_INHERITANCE_API 

This strategy expects OnTaskPriorityChange() events to support priority inheritance requests.

Definition at line 64 of file stk_strategy_fpriority.h.

65 {
66 WEIGHT_API = 1,
67 SLEEP_EVENT_API = 1,
70 };
@ WEIGHT_API
This strategy interprets GetWeight() as the task's fixed priority level (0 .. MAX_PRIORITIES - 1)....
@ DEADLINE_MISSED_API
This strategy does not use OnTaskDeadlineMissed() events.
@ SLEEP_EVENT_API
This strategy requires OnTaskSleep() / OnTaskWake() events to maintain per-priority runnable lists an...
@ PRIORITY_INHERITANCE_API
This strategy expects OnTaskPriorityChange() events to support priority inheritance requests.

◆ EPriority

template<uint8_t MAX_PRIORITIES>
enum stk::SwitchStrategyFixedPriority::EPriority

Symbolic priority level constants for common use cases.

Note
Concrete values depend on MAX_PRIORITIES. For SwitchStrategyFP32 (MAX_PRIORITIES = 32): PRIORITY_HIGHEST = 31, PRIORITY_HIGH = 23, PRIORITY_ABOVE_NORMAL = 17, PRIORITY_NORMAL = 16, PRIORITY_BELOW_NORMAL = 15, PRIORITY_LOWER = 8, PRIORITY_ABOVE_LOWEST = 1, PRIORITY_LOWEST = 0.
Enumerator
PRIORITY_HIGHEST 

Highest available priority level.

PRIORITY_HIGH 

High priority; mid-point between NORMAL and HIGHEST.

PRIORITY_ABOVE_NORMAL 

Slightly elevated priority; one step above NORMAL.

PRIORITY_NORMAL 

Mid-range priority level (MAX_PRIORITIES / 2).

PRIORITY_BELOW_NORMAL 

Slightly reduced priority; one step below NORMAL.

PRIORITY_LOWER 

Lower priority; mid-point between LOWEST and NORMAL.

PRIORITY_ABOVE_LOWEST 

Slightly elevated low priority; one step above LOWEST.

PRIORITY_LOWEST 

Lowest priority level; tasks only run when idle.

Definition at line 79 of file stk_strategy_fpriority.h.

80 {
82 PRIORITY_HIGH = ((MAX_PRIORITIES / 2) + (MAX_PRIORITIES - 1)) / 2,
87 PRIORITY_ABOVE_LOWEST = (0 + 1),
89 };
Fixed-priority preemptive scheduling strategy with round-robin arbitration within each priority level...
@ PRIORITY_LOWEST
Lowest priority level; tasks only run when idle.
@ PRIORITY_NORMAL
Mid-range priority level (MAX_PRIORITIES / 2).
@ PRIORITY_HIGH
High priority; mid-point between NORMAL and HIGHEST.
@ PRIORITY_ABOVE_NORMAL
Slightly elevated priority; one step above NORMAL.
@ PRIORITY_BELOW_NORMAL
Slightly reduced priority; one step below NORMAL.
@ PRIORITY_ABOVE_LOWEST
Slightly elevated low priority; one step above LOWEST.
@ PRIORITY_HIGHEST
Highest available priority level.
@ PRIORITY_LOWER
Lower priority; mid-point between LOWEST and NORMAL.

Constructor & Destructor Documentation

◆ SwitchStrategyFixedPriority()

template<uint8_t MAX_PRIORITIES>
stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::SwitchStrategyFixedPriority ( )
inlineexplicit

Construct an empty strategy with all priority levels empty, a clear bitmap, and null cursors.

Note
A compile-time assertion enforces MAX_PRIORITIES <= 32, matching the width of the 32-bit m_ready_bitmap. Instantiating with MAX_PRIORITIES > 32 is a compile error.

Definition at line 95 of file stk_strategy_fpriority.h.

96 {
97 STK_STATIC_ASSERT_DESC(MAX_PRIORITIES <= 32U, "MAX_PRIORITIES exceeds 32-bit bitmap width");
98 }
#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:429
IKernelTask * m_prev[MAX_PRIORITIES]
Per-priority round-robin cursor. m_prev[i] is the most recently scheduled task at level i,...
uint32_t m_ready_bitmap
Bitmask of non-empty priority levels: bit i is set when m_tasks[i] has at least one runnable task....
IKernelTask::ListHeadType m_tasks[MAX_PRIORITIES]
Per-priority runnable task lists. m_tasks[i] holds all runnable tasks at priority level i.
IKernelTask::ListHeadType m_sleep
Sleeping (blocked) tasks. Priority is retained in GetWeight() and restored on OnTaskWake().

◆ ~SwitchStrategyFixedPriority()

template<uint8_t MAX_PRIORITIES>
STK_VIRT_DTOR stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::~SwitchStrategyFixedPriority ( )
default

Destructor.

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

Member Function Documentation

◆ AddActive()

template<uint8_t MAX_PRIORITIES>
void stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::AddActive ( IKernelTask * task)
inlineprotected

Append a task to its priority level's runnable list and update the bitmap.

Parameters
[in]taskTask to make runnable.
Note
Appends to the back of m_tasks[prio].
Bitmap and cursor are only updated when the level was previously empty (GetSize() == 1 after LinkBack): m_ready_bitmap bit prio is set and m_prev[prio] is initialized to task. Subsequent additions at the same level leave the cursor untouched (the tail-adjustment in AddTask() handles the cursor for non-first additions).

Definition at line 302 of file stk_strategy_fpriority.h.

303 {
305
306 m_tasks[prio].LinkBack(task);
307
308 // init pointer
309 if (m_tasks[prio].GetSize() == 1U)
310 {
311 m_prev[prio] = task;
312
313 m_ready_bitmap |= (1U << prio);
314 }
315 }
static __stk_forceinline Priority GetTaskPriority(IKernelTask *task)
Get priority from the task.
size_t GetSize() const override
Get the total number of tasks managed by this strategy.

Referenced by stk::SwitchStrategyFixedPriority< 32 >::AddTask(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskWake(), and stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange().

Here is the caller graph for this function:

◆ AddTask()

template<uint8_t MAX_PRIORITIES>
void stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::AddTask ( IKernelTask * task)
inlineoverridevirtual

Add task to the runnable set at its fixed priority level.

Parameters
[in]taskTask to add. Must not be NULL and must not already be in any list.
Note
Priority is extracted by casting GetWeight() to uint8_t. The result must be less than MAX_PRIORITIES (asserted); passing a task whose GetWeight() is out of range is a programming error.
Delegates to AddActive() which appends the task to m_tasks[prio], sets m_ready_bitmap bit prio if this is the first task at that level, and initializes m_prev[prio].
Tail-cursor invariant (same as RR): if m_prev[prio] was already pointing at the tail before insertion, it is advanced to the new tail so GetNext() will include the new task in the very next rotation at this priority level.

Implements stk::ITaskSwitchStrategy.

Definition at line 117 of file stk_strategy_fpriority.h.

118 {
119 STK_ASSERT(task != nullptr);
120 STK_ASSERT(task->GetHead() == nullptr);
122
124 const bool is_tail = (m_prev[prio] == m_tasks[prio].GetLast());
125
127
128 // if pointer was pointing to the tail, become a tail
129 if (is_tail)
130 {
131 m_prev[prio] = task;
132 }
133 }
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:409
void AddActive(IKernelTask *task)
Append a task to its priority level's runnable list and update the bitmap.

◆ GetFirst()

template<uint8_t MAX_PRIORITIES>
IKernelTask * stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::GetFirst ( )
inlineoverridevirtual

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

Returns
The first task in the highest runnable priority level if any task is runnable (bitmap non-zero); otherwise the first task in m_sleep. Asserts if the combined set is empty (GetSize() == 0).
Note
Uses m_ready_bitmap to determine whether any runnable task exists, consistent with GetNext(). The sleep fallback allows the kernel to identify any task even when all are currently sleeping.

Implements stk::ITaskSwitchStrategy.

Definition at line 191 of file stk_strategy_fpriority.h.

192 {
193 STK_ASSERT(GetSize() != 0U);
194
195 IKernelTask *first_task = nullptr;
196
197 if (m_ready_bitmap == 0U)
198 {
199 first_task = (*m_sleep.GetFirst());
200 }
201 else
202 {
204 first_task = (*m_tasks[prio].GetFirst());
205 }
206
207 return first_task;
208 }
static __stk_forceinline Priority GetHighestReadyPriority(uint32_t bitmap)
Find the index of the highest set bit in bitmap.

◆ GetHighestReadyPriority()

template<uint8_t MAX_PRIORITIES>
__stk_forceinline Priority stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::GetHighestReadyPriority ( uint32_t bitmap)
inlinestaticprotected

Find the index of the highest set bit in bitmap.

Parameters
[in]bitmapBitmask of ready priority levels. Must not be 0 (behaviour is undefined for __builtin_clz(0); callers must check before calling).
Returns
Index of the most-significant set bit (0-based), which is the highest runnable priority level.
Note
On GCC/Clang: uses __builtin_clz for an O(1) hardware instruction (BSR on x86, CLZ on ARM). On other compilers: falls back to a portable O(32) linear scan from bit 31 down to 0.

Definition at line 377 of file stk_strategy_fpriority.h.

378 {
379 #if defined(__GNUC__)
381 #else
382 for (int8_t i = 31; i >= 0; --i)
383 {
384 if (bitmap & (1U << i))
385 {
387 }
388 }
389 return 0;
390 #endif
391 }
static __stk_forceinline Priority GetTaskPriorityFromWeight(int32_t weight)
Get priority from the task.

Referenced by stk::SwitchStrategyFixedPriority< 32 >::GetFirst(), and stk::SwitchStrategyFixedPriority< 32 >::GetNext().

Here is the caller graph for this function:

◆ GetNext()

template<uint8_t MAX_PRIORITIES>
IKernelTask * stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::GetNext ( )
inlineoverridevirtual

Select and return the next task to run.

Returns
The next task in the highest runnable priority level's round-robin rotation, or nullptr if no runnable tasks exist (m_ready_bitmap == 0, kernel sleeps).
Note
Priority selection is O(1) via GetHighestReadyPriority() on m_ready_bitmap. Within the selected level the cursor (m_prev[prio]) is advanced by one position in the closed-loop list, implementing round-robin within the level.
Tasks at a lower priority are never returned while any higher-priority task has its bitmap bit set — preemption is enforced entirely by the bitmap lookup.

Implements stk::ITaskSwitchStrategy.

Definition at line 168 of file stk_strategy_fpriority.h.

169 {
170 IKernelTask *next = nullptr;
171
172 if (m_ready_bitmap != 0U)
173 {
175
176 next = (*m_prev[prio]->GetNext());
177 m_prev[prio] = next;
178 }
179
180 return next;
181 }

◆ GetSize()

template<uint8_t MAX_PRIORITIES>
size_t stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::GetSize ( ) const
inlineoverridevirtual

Get the total number of tasks managed by this strategy.

Returns
Sum of tasks across all priority levels in m_tasks plus tasks in m_sleep.
Note
O(MAX_PRIORITIES): iterates all priority levels to accumulate the count. Unlike the RR and SWRR strategies this is not O(1).

Implements stk::ITaskSwitchStrategy.

Definition at line 215 of file stk_strategy_fpriority.h.

216 {
217 size_t total = m_sleep.GetSize();
218 for (Priority i = 0U; i < MAX_PRIORITIES; ++i)
219 {
220 total += m_tasks[i].GetSize();
221 }
222
223 return total;
224 }

Referenced by stk::SwitchStrategyFixedPriority< 32 >::AddActive(), stk::SwitchStrategyFixedPriority< 32 >::GetFirst(), and stk::SwitchStrategyFixedPriority< 32 >::RemoveTask().

Here is the caller graph for this function:

◆ GetTaskPriority()

template<uint8_t MAX_PRIORITIES>
__stk_forceinline Priority stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::GetTaskPriority ( IKernelTask * task)
inlinestaticprotected

Get priority from the task.

Parameters
[in]taskPointer to the task. Priority is read from GetWeight().
Returns
Priority level.

Definition at line 363 of file stk_strategy_fpriority.h.

364 {
365 return GetTaskPriorityFromWeight(task->GetWeight());
366 }

Referenced by stk::SwitchStrategyFixedPriority< 32 >::AddActive(), stk::SwitchStrategyFixedPriority< 32 >::AddTask(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskSleep(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange(), and stk::SwitchStrategyFixedPriority< 32 >::RemoveTask().

Here is the caller graph for this function:

◆ GetTaskPriorityFromWeight()

template<uint8_t MAX_PRIORITIES>
__stk_forceinline Priority stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::GetTaskPriorityFromWeight ( int32_t weight)
inlinestaticprotected

Get priority from the task.

Parameters
[in]weightWeight of the task read from GetWeight().
Returns
Weight value.

Definition at line 354 of file stk_strategy_fpriority.h.

355 {
356 return static_cast<Priority>(weight);
357 }

Referenced by stk::SwitchStrategyFixedPriority< 32 >::GetHighestReadyPriority(), stk::SwitchStrategyFixedPriority< 32 >::GetTaskPriority(), and stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange().

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 1090 of file stk_common.h.

1091 {
1092 STK_UNUSED(task);
1093 return false;
1094 }
#define STK_UNUSED(X)
Explicitly marks a variable as unused to suppress compiler warnings.
Definition stk_defs.h:608

References STK_UNUSED.

◆ OnTaskSleep()

template<uint8_t MAX_PRIORITIES>
void stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::OnTaskSleep ( IKernelTask * task)
inlineoverridevirtual

Notification that a task has entered the sleeping state.

Parameters
[in]taskThe task that is now sleeping. Must be in m_tasks[priority] (asserted).
Note
Delegates to RemoveActive() which unlinks the task from its priority level list, updates the per-level cursor, and clears bit prio in m_ready_bitmap if this was the last runnable task at that level. Then appends the task to m_sleep.

Implements stk::ITaskSwitchStrategy.

Definition at line 232 of file stk_strategy_fpriority.h.

233 {
234 STK_ASSERT(task != nullptr);
235 STK_ASSERT(task->IsSleeping());
236 STK_ASSERT(task->GetHead() == &m_tasks[GetTaskPriority(task)]);
237
239 m_sleep.LinkBack(task);
240 }
void RemoveActive(IKernelTask *task, const Priority prio)
Remove a task from its priority level's runnable list and update the bitmap/cursor.

◆ OnTaskWake()

template<uint8_t MAX_PRIORITIES>
void stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::OnTaskWake ( IKernelTask * task)
inlineoverridevirtual

Notification that a task has become runnable again.

Parameters
[in]taskThe task that woke up. Must be in m_sleep (asserted).
Note
Unlinks the task from m_sleep and delegates to AddActive() which appends it to m_tasks[priority] and sets the bitmap bit if the level was empty.
Unlike SwitchStrategySmoothWeightedRoundRobin, no priority boost is applied. The waking task re-enters its natural priority level and waits its turn in the round-robin rotation at that level. Its preemption guarantee is provided solely by its fixed priority relative to other runnable levels.

Implements stk::ITaskSwitchStrategy.

Definition at line 251 of file stk_strategy_fpriority.h.

252 {
253 STK_ASSERT(task != nullptr);
254 STK_ASSERT(!task->IsSleeping());
255 STK_ASSERT(task->GetHead() == &m_sleep);
256
257 m_sleep.Unlink(task);
259 }

◆ OnTaskWeightChange()

template<uint8_t MAX_PRIORITIES>
void stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::OnTaskWeightChange ( IKernelTask * task,
Weight old_weight )
inlineoverridevirtual

Move a runnable task to a new priority level after its weight changed.

Parameters
[in]taskTask whose weight was just updated.
[in]old_weightPriority level the task occupied before the change.
Note
Removes from the old-priority list (using old_weight to locate it), then re-inserts via AddActive() which reads the new GetWeight(). m_ready_bitmap is updated by both RemoveActive and AddActive.
No-op if old and new priority are identical.
Called from within a hw::CriticalSection.

Reimplemented from stk::ITaskSwitchStrategy.

Definition at line 270 of file stk_strategy_fpriority.h.

271 {
273
276
277 if (task->GetHead() != &m_sleep)
278 {
279 STK_ASSERT(task->GetHead() == &m_tasks[old_prio]);
280
281 // remove from the old priority list
283
284 // re-add to the current priority list
286 }
287 }

◆ RemoveActive()

template<uint8_t MAX_PRIORITIES>
void stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::RemoveActive ( IKernelTask * task,
const Priority prio )
inlineprotected

Remove a task from its priority level's runnable list and update the bitmap/cursor.

Parameters
[in]taskRunnable task to remove.
[in]prioPriority of the task with which it was registered with AddActive.
Note
Cursor update algorithm (same as SwitchStrategyRoundRobin::RemoveActive, applied per priority level):
  • Capture next = task->GetNext() before unlinking.
  • If next != task (other tasks remain at this level): set m_prev[prio] = next->GetPrev() so GetNext() returns next without skipping it.
  • If next == task (last task at this level): set m_prev[prio] = NULL and clear bit prio in m_ready_bitmap. GetNext() will then select the next highest set bit, falling through to a lower priority level.

Definition at line 330 of file stk_strategy_fpriority.h.

331 {
332 IKernelTask *next = (*task->GetNext());
333
334 m_tasks[prio].Unlink(task);
335
336 // update pointer
337 if (next != task)
338 {
339 m_prev[prio] = (*next->GetPrev());
340 }
341 else
342 {
343 m_prev[prio] = nullptr;
344
345 // this will cause a switch to a lower priority task list
346 m_ready_bitmap &= ~(1U << prio);
347 }
348 }
IKernelTask * GetNext() override
Select and return the next task to run.

Referenced by stk::SwitchStrategyFixedPriority< 32 >::OnTaskSleep(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange(), and stk::SwitchStrategyFixedPriority< 32 >::RemoveTask().

Here is the caller graph for this function:

◆ RemoveTask()

template<uint8_t MAX_PRIORITIES>
void stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::RemoveTask ( IKernelTask * task)
inlineoverridevirtual

Remove task from whichever list it currently occupies.

Parameters
[in]taskTask to remove. Must not be NULL and must belong to either m_tasks[priority] or m_sleep (asserted).
Note
Dispatch checks m_sleep first (reversed from the RR/SWRR pattern). If sleeping, simply unlinks from m_sleep. If runnable, delegates to RemoveActive() which also updates the cursor and clears the bitmap bit if the priority level becomes empty.

Implements stk::ITaskSwitchStrategy.

Definition at line 143 of file stk_strategy_fpriority.h.

144 {
145 STK_ASSERT(task != nullptr);
146 STK_ASSERT(GetSize() != 0U);
147 STK_ASSERT((task->GetHead() == &m_tasks[GetTaskPriority(task)]) || (task->GetHead() == &m_sleep));
148
149 if (task->GetHead() == &m_sleep)
150 {
151 m_sleep.Unlink(task);
152 }
153 else
154 {
156 }
157 }

◆ STK_NONCOPYABLE_CLASS()

template<uint8_t MAX_PRIORITIES>
stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::STK_NONCOPYABLE_CLASS ( SwitchStrategyFixedPriority< MAX_PRIORITIES > )
private

Member Data Documentation

◆ m_prev

template<uint8_t MAX_PRIORITIES>
IKernelTask* stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::m_prev[MAX_PRIORITIES]
private

Per-priority round-robin cursor. m_prev[i] is the most recently scheduled task at level i, or nullptr when level i is empty. GetNext() advances from this position.

Definition at line 399 of file stk_strategy_fpriority.h.

◆ m_ready_bitmap

template<uint8_t MAX_PRIORITIES>
uint32_t stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::m_ready_bitmap
private

Bitmask of non-empty priority levels: bit i is set when m_tasks[i] has at least one runnable task. Updated by AddActive() (bit set) and RemoveActive() (bit cleared on last removal).

Definition at line 398 of file stk_strategy_fpriority.h.

◆ m_sleep

template<uint8_t MAX_PRIORITIES>
IKernelTask::ListHeadType stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::m_sleep
private

Sleeping (blocked) tasks. Priority is retained in GetWeight() and restored on OnTaskWake().

Definition at line 397 of file stk_strategy_fpriority.h.

◆ m_tasks

template<uint8_t MAX_PRIORITIES>
IKernelTask::ListHeadType stk::SwitchStrategyFixedPriority< MAX_PRIORITIES >::m_tasks[MAX_PRIORITIES]
private

Per-priority runnable task lists. m_tasks[i] holds all runnable tasks at priority level i.

Definition at line 396 of file stk_strategy_fpriority.h.


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