|
SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
|
Fixed-priority preemptive scheduling strategy with round-robin arbitration within each priority level. More...
#include <stk_strategy_fpriority.h>
Public Types | |
| enum | EConfig { WEIGHT_API = 1 , SLEEP_EVENT_API = 1 , DEADLINE_MISSED_API = 0 , PRIORITY_INHERITANCE_API = 1 , NOSLEEP_YIELD_API = NoSleepYield , TIMESLICE_API = 0 } |
| 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. | |
| IKernelTask * | GetNext () override |
| Select and return the next task to run. | |
| IKernelTask * | GetFirst () 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. | |
| bool | OnTaskYield (IKernelTask *task) override |
| Notification that the running task called Yield() (non-HRT kernel modes only). | |
| virtual bool | OnTaskTimeSlice (IKernelTask *task) |
| Notification that the running task's time slice expired (KERNEL_TIMESLICE only). | |
| 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). | |
| IKernelTask * | m_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. | |
Fixed-priority preemptive scheduling strategy with round-robin arbitration within each priority level.
| MAX_PRIORITIES | Number 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. |
| NoSleepYield | If true, Yield() keeps the task in the runnable set and hands the CPU to the next task at the same priority level (see OnTaskYield). If false (default), the kernel performs the legacy yield: the task sleeps for YIELD_TICKS, which also lets lower-priority tasks run during that tick. |
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.N will never run while any task at priority > N is runnable.m_prev[prio]).NoSleepYield is true, OnTaskYield() moves the yielding task's per-level cursor onto the task itself, so the following GetNext() returns its successor at the same priority level. If the task is alone at its level, it is selected again (no context switch): a yield never hands the CPU to a lower priority level, unlike the legacy sleep-based yield.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).GetWeight() is interpreted as the task's fixed priority level. The dynamic weight functions (SetCurrentWeight / GetCurrentWeight) are not used by this strategy. m_ready_bitmap accurate. Definition at line 69 of file stk_strategy_fpriority.h.
|
protected |
Priority type.
Definition at line 339 of file stk_strategy_fpriority.h.
| 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 |
| DEADLINE_MISSED_API | This strategy does not use OnTaskDeadlineMissed() events. |
| PRIORITY_INHERITANCE_API | This strategy expects OnTaskPriorityChange() events to support priority inheritance requests. |
| NOSLEEP_YIELD_API | (1) enables OnTaskYield(): yielding task stays runnable and hands the CPU to same-priority peers. |
| TIMESLICE_API | This strategy does not support KERNEL_TIMESLICE mode. |
Definition at line 75 of file stk_strategy_fpriority.h.
| enum stk::SwitchStrategyFixedPriority::EPriority |
Symbolic priority level constants for common use cases.
Definition at line 92 of file stk_strategy_fpriority.h.
|
inlineexplicit |
Construct an empty strategy with all priority levels empty, a clear bitmap, and null cursors.
m_ready_bitmap. Instantiating with MAX_PRIORITIES > 32 is a compile error. Definition at line 108 of file stk_strategy_fpriority.h.
|
default |
Destructor.
|
inlineprotected |
Append a task to its priority level's runnable list and update the bitmap.
| [in] | task | Task to make runnable. |
m_tasks[prio]. 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 350 of file stk_strategy_fpriority.h.
Referenced by stk::SwitchStrategyFixedPriority< 32 >::AddTask(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskWake(), and stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange().
|
inlineoverridevirtual |
Add task to the runnable set at its fixed priority level.
| [in] | task | Task to add. Must not be NULL and must not already be in any list. |
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. m_tasks[prio], sets m_ready_bitmap bit prio if this is the first task at that level, and initializes m_prev[prio]. 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 130 of file stk_strategy_fpriority.h.
|
inlineoverridevirtual |
Get the first task in the managed set (used by the kernel for initial scheduling).
m_sleep. Asserts if the combined set is empty (GetSize() == 0). 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 204 of file stk_strategy_fpriority.h.
|
inlinestaticprotected |
Find the index of the highest set bit in bitmap.
| [in] | bitmap | Bitmask of ready priority levels. Must not be 0 (behaviour is undefined for __builtin_clz(0); callers must check before calling). |
__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 432 of file stk_strategy_fpriority.h.
Referenced by stk::SwitchStrategyFixedPriority< 32 >::GetFirst(), and stk::SwitchStrategyFixedPriority< 32 >::GetNext().
|
inlineoverridevirtual |
Select and return the next task to run.
nullptr if no runnable tasks exist (m_ready_bitmap == 0, kernel sleeps). 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. Implements stk::ITaskSwitchStrategy.
Definition at line 181 of file stk_strategy_fpriority.h.
|
inlineoverridevirtual |
Get the total number of tasks managed by this strategy.
m_tasks plus tasks in m_sleep. Implements stk::ITaskSwitchStrategy.
Definition at line 228 of file stk_strategy_fpriority.h.
Referenced by stk::SwitchStrategyFixedPriority< 32 >::AddActive(), stk::SwitchStrategyFixedPriority< 32 >::GetFirst(), and stk::SwitchStrategyFixedPriority< 32 >::RemoveTask().
|
inlinestaticprotected |
Get priority from the task.
| [in] | task | Pointer to the task. Priority is read from GetWeight(). |
Definition at line 418 of file stk_strategy_fpriority.h.
Referenced by stk::SwitchStrategyFixedPriority< 32 >::AddActive(), stk::SwitchStrategyFixedPriority< 32 >::AddTask(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskSleep(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskYield(), and stk::SwitchStrategyFixedPriority< 32 >::RemoveTask().
|
inlinestaticprotected |
Get priority from the task.
| [in] | weight | Weight of the task read from GetWeight(). |
Definition at line 409 of file stk_strategy_fpriority.h.
Referenced by stk::SwitchStrategyFixedPriority< 32 >::GetHighestReadyPriority(), stk::SwitchStrategyFixedPriority< 32 >::GetTaskPriority(), and stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange().
|
inlinevirtualinherited |
Notification that a task has exceeded its HRT deadline; returns whether the strategy can recover without a hard fault.
| [in] | task | The task whose deadline was missed. Must not be nullptr. |
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. 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(). 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." false (unrecoverable), which is the correct default for strategies that do not implement overrun recovery. Definition at line 1487 of file stk_common.h.
References STK_UNUSED.
|
inlineoverridevirtual |
Notification that a task has entered the sleeping state.
| [in] | task | The task that is now sleeping. Must be in m_tasks[priority] (asserted). |
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 245 of file stk_strategy_fpriority.h.
|
inlinevirtualinherited |
Notification that the running task's time slice expired (KERNEL_TIMESLICE only).
| [in] | task | Pointer to the running task, currently in the runnable set. |
true if the strategy rotated to a same-priority peer (the following GetNext() returns it); false to keep running the task (no peer, or the task is not eligible for time-slicing). TIMESLICE_API == 1. Reimplemented in stk::SwitchStrategyPreemptionThreshold< MAX_PRIORITIES, TIMESLICE >, stk::SwitchStrategyPreemptionThreshold< 32 >, and stk::SwitchStrategyPreemptionThreshold< 32, true >.
Definition at line 1461 of file stk_common.h.
References STK_UNUSED.
|
inlineoverridevirtual |
Notification that a task has become runnable again.
| [in] | task | The task that woke up. Must be in m_sleep (asserted). |
m_sleep and delegates to AddActive() which appends it to m_tasks[priority] and sets the bitmap bit if the level was empty. Implements stk::ITaskSwitchStrategy.
Definition at line 264 of file stk_strategy_fpriority.h.
|
inlineoverridevirtual |
Move a runnable task to a new priority level after its weight changed.
| [in] | task | Task whose weight was just updated. |
| [in] | old_weight | Priority level the task occupied before the change. |
Reimplemented from stk::ITaskSwitchStrategy.
Definition at line 283 of file stk_strategy_fpriority.h.
|
inlineoverridevirtual |
Notification that the running task called Yield() (non-HRT kernel modes only).
| [in] | task | Pointer to the yielding task, currently in the runnable set. |
true if the strategy handled the yield itself: the task stays runnable (it is NOT put to sleep) and the following GetNext() returns its successor at the same priority level, or the task itself if it is alone at its level (a yield never selects a lower priority level); false if the kernel shall perform the legacy yield, i.e. sleep the task for YIELD_TICKS. Reimplemented from stk::ITaskSwitchStrategy.
Definition at line 313 of file stk_strategy_fpriority.h.
|
inlineprotected |
Remove a task from its priority level's runnable list and update the bitmap/cursor.
| [in] | task | Runnable task to remove. |
| [in] | prio | Priority of the task with which it was registered with AddActive. |
next = task->GetNext() before unlinking.next != task (other tasks remain at this level) and the cursor m_prev[prio] pointed at the removed task: set m_prev[prio] = next->GetPrev() so GetNext() returns next without skipping it. If the cursor pointed at another task it is left untouched so that the rotation is not disturbed.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 380 of file stk_strategy_fpriority.h.
Referenced by stk::SwitchStrategyFixedPriority< 32 >::OnTaskSleep(), stk::SwitchStrategyFixedPriority< 32 >::OnTaskWeightChange(), and stk::SwitchStrategyFixedPriority< 32 >::RemoveTask().
|
inlineoverridevirtual |
Remove task from whichever list it currently occupies.
| [in] | task | Task to remove. Must not be NULL and must belong to either m_tasks[priority] or m_sleep (asserted). |
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 156 of file stk_strategy_fpriority.h.
|
private |
|
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 443 of file stk_strategy_fpriority.h.
|
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 442 of file stk_strategy_fpriority.h.
|
private |
Sleeping (blocked) tasks. Priority is retained in GetWeight() and restored on OnTaskWake().
Definition at line 441 of file stk_strategy_fpriority.h.
|
private |
Per-priority runnable task lists. m_tasks[i] holds all runnable tasks at priority level i.
Definition at line 440 of file stk_strategy_fpriority.h.