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
stktest_switchstrategyroundrobin.cpp
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#include "stktest.h"
11
12namespace stk {
13namespace test {
14
15// ============================================================================ //
16// ============================ SwitchStrategyRR ====================== //
17// ============================================================================ //
18
20{
21 void setup() {}
22 void teardown()
23 {
24 g_TestContext.ExpectAssert(false);
25 g_TestContext.RethrowAssertException(true);
26 }
27};
28
30{
32
33 try
34 {
35 g_TestContext.ExpectAssert(true);
36 rr.GetFirst();
37 CHECK_TEXT(false, "expecting assertion when empty");
38 }
39 catch (TestAssertPassed &pass)
40 {
41 CHECK(true);
42 g_TestContext.ExpectAssert(false);
43 }
44}
45
47{
50 ITaskSwitchStrategy *strategy = kernel.GetSwitchStrategy();
51
52 kernel.Initialize();
53
54 kernel.AddTask(&task1);
55 kernel.RemoveTask(&task1);
56 CHECK_EQUAL(0, strategy->GetSize());
57
58 // expect to return NULL which puts core into a sleep mode, current is ignored by this strategy
59 CHECK_EQUAL(0, strategy->GetNext());
60}
61
62TEST(SwitchStrategyRoundRobin, OnTaskDeadlineMissedNotSupported)
63{
66 ITaskSwitchStrategy *strategy = kernel.GetSwitchStrategy();
67
68 kernel.Initialize();
69 kernel.AddTask(&task1);
70
71 try
72 {
73 g_TestContext.ExpectAssert(true);
74 strategy->OnTaskDeadlineMissed(strategy->GetFirst());
75 CHECK_TEXT(false, "expecting assertion - OnTaskDeadlineMissed not supported");
76 }
77 catch (TestAssertPassed &pass)
78 {
79 CHECK(true);
80 g_TestContext.ExpectAssert(false);
81 }
82
83 // we need this workaround to pass 100% coverage test by blocking the exception
84 g_TestContext.ExpectAssert(true);
85 g_TestContext.RethrowAssertException(false);
86 strategy->OnTaskDeadlineMissed(strategy->GetFirst());
87}
88
90{
92 TaskMock<ACCESS_USER> task1, task2, task3;
93 ITaskSwitchStrategy *strategy = kernel.GetSwitchStrategy();
94
95 kernel.Initialize();
96 kernel.AddTask(&task1);
97 kernel.AddTask(&task2);
98 kernel.AddTask(&task3);
99
100 IKernelTask *first = strategy->GetFirst();
101 CHECK_EQUAL_TEXT(&task1, first->GetUserTask(), "expecting first task1");
102
103 IKernelTask *next = strategy->GetNext();
104 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "expecting next task1");
105
106 next = strategy->GetNext();
107 CHECK_EQUAL_TEXT(&task2, next->GetUserTask(), "expecting next task2");
108
109 next = strategy->GetNext();
110 CHECK_EQUAL_TEXT(&task3, next->GetUserTask(), "expecting next task3");
111
112 next = strategy->GetNext();
113 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "expecting next task1 again (endless looping)");
114
115 next = strategy->GetNext();
116 CHECK_EQUAL_TEXT(&task2, next->GetUserTask(), "expecting next task2 again (endless looping)");
117
118 kernel.RemoveTask(&task2);
119
120 next = strategy->GetNext();
121 CHECK_EQUAL_TEXT(&task3, next->GetUserTask(), "expecting next task3 again (endless looping)");
122
123 next = strategy->GetNext();
124 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "expecting next task1 again (endless looping)");
125}
126
128{
129 // Create kernel with 3 tasks
131 TaskMock<ACCESS_USER> task1, task2, task3;
132
133 kernel.Initialize();
134
135 // Add tasks
136 kernel.AddTask(&task1);
137
138 ITaskSwitchStrategy *strategy = kernel.GetSwitchStrategy();
139
140 IKernelTask *next = strategy->GetFirst();
141
142 // --- Stage 1: 1 task only ---------------------------------------------
143
144 // Always returns the same task
145 for (int32_t i = 0; i < 5; i++)
146 {
147 next = strategy->GetNext();
148 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "Single task must always be selected");
149 }
150
151 // --- Stage 2: add second task -----------------------------------------
152
153 kernel.AddTask(&task2);
154
155 next = strategy->GetNext(); // should still return task1 as task2 will be scheduled after this call
156 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "Next task should be task1");
157 next = strategy->GetNext(); // should return task2
158 CHECK_EQUAL_TEXT(&task2, next->GetUserTask(), "Next task should be task2");
159 next = strategy->GetNext(); // should wrap around to task1
160 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "Next task should wrap to task1");
161
162 // --- Stage 3: add third task ------------------------------------------
163
164 kernel.AddTask(&task3);
165
166 // Expected sequence: task1 -> task2 -> task3 -> task1 ...
167 next = strategy->GetNext(); // task2
168 CHECK_EQUAL_TEXT(&task2, next->GetUserTask(), "Next task should be task2");
169 next = strategy->GetNext(); // task3
170 CHECK_EQUAL_TEXT(&task3, next->GetUserTask(), "Next task should be task3");
171 next = strategy->GetNext(); // task1
172 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "Next task should wrap to task1");
173
174 // --- Stage 4: remove a task -------------------------------------------
175
176 kernel.RemoveTask(&task2);
177
178 // Expected sequence: task1 -> task3 -> task1 -> task3 ...
179 next = strategy->GetNext(); // task3
180 CHECK_EQUAL_TEXT(&task3, next->GetUserTask(), "Next task should be task3 after removal");
181 next = strategy->GetNext(); // task1
182 CHECK_EQUAL_TEXT(&task1, next->GetUserTask(), "Next task should be task1 after removal");
183 next = strategy->GetNext(); // task3
184 CHECK_EQUAL_TEXT(&task3, next->GetUserTask(), "Next task should wrap to task3");
185}
186
187} // namespace stk
188} // namespace test
Namespace of STK package.
SwitchStrategyRoundRobin SwitchStrategyRR
Shorthand alias for SwitchStrategyRoundRobin.
Namespace of the test inventory.
TestContext g_TestContext
Global instance of the TestContext.
Definition stktest.cpp:16
TEST_GROUP(Kernel)
TEST(Kernel, MaxTasks)
Concrete implementation of IKernel.
Definition stk.h:83
void Initialize(uint32_t resolution_us=PERIODICITY_DEFAULT)
Prepare kernel for use: reset state, configure the platform, and register the service singleton.
Definition stk.h:805
ITaskSwitchStrategy * GetSwitchStrategy()
Get task-switching strategy instance owned by this kernel.
Definition stk.h:959
void RemoveTask(ITask *user_task)
Remove a previously added task from the kernel before Start().
Definition stk.h:895
void AddTask(ITask *user_task)
Register task for a soft real-time (SRT) scheduling.
Definition stk.h:832
Scheduling-strategy-facing interface for a kernel task slot.
Definition stk_common.h:493
virtual ITask * GetUserTask()=0
Get user task.
Interface for a task switching strategy implementation.
Definition stk_common.h:782
virtual size_t GetSize() const =0
Get number of tasks currently managed by this strategy.
virtual IKernelTask * GetNext()=0
Advance the internal iterator and return the next runnable task.
virtual IKernelTask * GetFirst() const =0
Get first task.
virtual bool OnTaskDeadlineMissed(IKernelTask *task)=0
Notification that a task has exceeded its HRT deadline; returns whether the strategy can recover with...
Round-Robin task-switching strategy: each runnable task receives one time slice (one tick interval) i...
IKernelTask * GetFirst() const
Get first task in the managed set (used by the kernel for initial scheduling).
Throwable class for catching assertions from STK_ASSERT_HANDLER().
Definition stktest.h:67