SimpleKernel 1.17.0
Loading...
Searching...
No Matches
fifo_scheduler_test.cpp File Reference
#include "fifo_scheduler.hpp"
#include <gtest/gtest.h>
#include "kstd_vector"
#include "task_control_block.hpp"
Include dependency graph for fifo_scheduler_test.cpp:

Go to the source code of this file.

Functions

 TEST (FifoSchedulerTest, BasicEnqueueDequeue)
 
 TEST (FifoSchedulerTest, FifoOrdering)
 
 TEST (FifoSchedulerTest, DequeueSpecificTask)
 
 TEST (FifoSchedulerTest, DequeueFirstTask)
 
 TEST (FifoSchedulerTest, DequeueLastTask)
 
 TEST (FifoSchedulerTest, Statistics)
 
 TEST (FifoSchedulerTest, RepeatedEnqueue)
 
 TEST (FifoSchedulerTest, MixedOperations)
 
 TEST (FifoSchedulerTest, EmptyQueueRobustness)
 
 TEST (FifoSchedulerTest, LargeNumberOfTasks)
 
 TEST (FifoSchedulerTest, OnTickHook)
 
 TEST (FifoSchedulerTest, OnTimeSliceExpiredHook)
 
 TEST (FifoSchedulerTest, PriorityHooks)
 
 TEST (FifoSchedulerTest, SchedulerHooks)
 

Function Documentation

◆ TEST() [1/14]

TEST ( FifoSchedulerTest  ,
BasicEnqueueDequeue   
)

Definition at line 13 of file fifo_scheduler_test.cpp.

13 {
14 FifoScheduler scheduler;
15
16 // 验证调度器名称
17 EXPECT_STREQ(scheduler.name, "FIFO");
18
19 // 创建测试任务
20 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
21 task1.status = TaskStatus::kReady;
22
23 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
24 task2.status = TaskStatus::kReady;
25
26 // 测试空队列
27 EXPECT_TRUE(scheduler.IsEmpty());
28 EXPECT_EQ(scheduler.GetQueueSize(), 0);
29 EXPECT_EQ(scheduler.PickNext(), nullptr);
30
31 // 加入任务
32 scheduler.Enqueue(&task1);
33 EXPECT_FALSE(scheduler.IsEmpty());
34 EXPECT_EQ(scheduler.GetQueueSize(), 1);
35
36 scheduler.Enqueue(&task2);
37 EXPECT_EQ(scheduler.GetQueueSize(), 2);
38
39 // 测试 FIFO 顺序(先进先出)
40 EXPECT_EQ(scheduler.PickNext(), &task1);
41 EXPECT_EQ(scheduler.GetQueueSize(), 1);
42
43 EXPECT_EQ(scheduler.PickNext(), &task2);
44 EXPECT_EQ(scheduler.GetQueueSize(), 0);
45
46 EXPECT_EQ(scheduler.PickNext(), nullptr);
47 EXPECT_TRUE(scheduler.IsEmpty());
48}
先来先服务 (FIFO) 调度器
auto Enqueue(TaskControlBlock *task) -> void override
将任务加入就绪队列尾部
auto PickNext() -> TaskControlBlock *override
选择下一个要运行的任务(队列头部)
auto IsEmpty() const -> bool override
判断队列是否为空
auto GetQueueSize() const -> size_t override
获取就绪队列大小
const char * name
调度器名称
constexpr etl::fsm_state_id_t kReady
Definition task_fsm.hpp:15
任务控制块,管理进程/线程的核心数据结构
#define EXPECT_TRUE(cond, msg)
#define EXPECT_FALSE(cond, msg)
#define EXPECT_EQ(val1, val2, msg)
Here is the call graph for this function:

◆ TEST() [2/14]

TEST ( FifoSchedulerTest  ,
DequeueFirstTask   
)

Definition at line 100 of file fifo_scheduler_test.cpp.

100 {
101 FifoScheduler scheduler;
102
103 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
104 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
105 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
106
107 scheduler.Enqueue(&task1);
108 scheduler.Enqueue(&task2);
109 scheduler.Enqueue(&task3);
110
111 // 移除队首任务
112 scheduler.Dequeue(&task1);
113 EXPECT_EQ(scheduler.GetQueueSize(), 2);
114
115 // task2 现在应该是队首
116 EXPECT_EQ(scheduler.PickNext(), &task2);
117 EXPECT_EQ(scheduler.PickNext(), &task3);
118 EXPECT_EQ(scheduler.PickNext(), nullptr);
119}
auto Dequeue(TaskControlBlock *task) -> void override
从就绪队列中移除指定任务
Here is the call graph for this function:

◆ TEST() [3/14]

TEST ( FifoSchedulerTest  ,
DequeueLastTask   
)

Definition at line 122 of file fifo_scheduler_test.cpp.

122 {
123 FifoScheduler scheduler;
124
125 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
126 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
127 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
128
129 scheduler.Enqueue(&task1);
130 scheduler.Enqueue(&task2);
131 scheduler.Enqueue(&task3);
132
133 // 移除队尾任务
134 scheduler.Dequeue(&task3);
135 EXPECT_EQ(scheduler.GetQueueSize(), 2);
136
137 EXPECT_EQ(scheduler.PickNext(), &task1);
138 EXPECT_EQ(scheduler.PickNext(), &task2);
139 EXPECT_EQ(scheduler.PickNext(), nullptr);
140}
Here is the call graph for this function:

◆ TEST() [4/14]

TEST ( FifoSchedulerTest  ,
DequeueSpecificTask   
)

Definition at line 76 of file fifo_scheduler_test.cpp.

76 {
77 FifoScheduler scheduler;
78
79 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
80 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
81 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
82
83 scheduler.Enqueue(&task1);
84 scheduler.Enqueue(&task2);
85 scheduler.Enqueue(&task3);
86
87 EXPECT_EQ(scheduler.GetQueueSize(), 3);
88
89 // 移除中间的任务
90 scheduler.Dequeue(&task2);
91 EXPECT_EQ(scheduler.GetQueueSize(), 2);
92
93 // 验证只剩下 task1 和 task3
94 EXPECT_EQ(scheduler.PickNext(), &task1);
95 EXPECT_EQ(scheduler.PickNext(), &task3);
96 EXPECT_EQ(scheduler.PickNext(), nullptr);
97}
Here is the call graph for this function:

◆ TEST() [5/14]

TEST ( FifoSchedulerTest  ,
EmptyQueueRobustness   
)

Definition at line 239 of file fifo_scheduler_test.cpp.

239 {
240 FifoScheduler scheduler;
241
242 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
243
244 // 空队列操作
245 EXPECT_EQ(scheduler.PickNext(), nullptr);
246 EXPECT_EQ(scheduler.PickNext(), nullptr);
247 EXPECT_EQ(scheduler.GetQueueSize(), 0);
248 EXPECT_TRUE(scheduler.IsEmpty());
249
250 // 尝试移除不存在的任务(应该不崩溃)
251 scheduler.Dequeue(&task1);
252 EXPECT_EQ(scheduler.GetQueueSize(), 0);
253
254 // 加入后再测试
255 scheduler.Enqueue(&task1);
256 EXPECT_EQ(scheduler.GetQueueSize(), 1);
257
258 // 移除存在的任务
259 scheduler.Dequeue(&task1);
260 EXPECT_EQ(scheduler.GetQueueSize(), 0);
261 EXPECT_TRUE(scheduler.IsEmpty());
262}
Here is the call graph for this function:

◆ TEST() [6/14]

TEST ( FifoSchedulerTest  ,
FifoOrdering   
)

Definition at line 51 of file fifo_scheduler_test.cpp.

51 {
52 FifoScheduler scheduler;
53
54 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
55 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
56 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
57 TaskControlBlock task4("Task4", 4, nullptr, nullptr);
58
59 // 按顺序加入任务
60 scheduler.Enqueue(&task1);
61 scheduler.Enqueue(&task2);
62 scheduler.Enqueue(&task3);
63 scheduler.Enqueue(&task4);
64
65 EXPECT_EQ(scheduler.GetQueueSize(), 4);
66
67 // 验证严格的 FIFO 顺序
68 EXPECT_EQ(scheduler.PickNext(), &task1);
69 EXPECT_EQ(scheduler.PickNext(), &task2);
70 EXPECT_EQ(scheduler.PickNext(), &task3);
71 EXPECT_EQ(scheduler.PickNext(), &task4);
72 EXPECT_EQ(scheduler.PickNext(), nullptr);
73}
Here is the call graph for this function:

◆ TEST() [7/14]

TEST ( FifoSchedulerTest  ,
LargeNumberOfTasks   
)

Definition at line 265 of file fifo_scheduler_test.cpp.

265 {
266 FifoScheduler scheduler;
267 constexpr size_t kTaskCount = 100;
268
269 // 创建任务数组(使用动态分配)
270 kstd::vector<TaskControlBlock*> tasks;
271 for (size_t i = 0; i < kTaskCount; ++i) {
272 auto* task = new TaskControlBlock("Task", 10, nullptr, nullptr);
273 task->status = TaskStatus::kReady;
274 tasks.push_back(task);
275 scheduler.Enqueue(task);
276 }
277
278 EXPECT_EQ(scheduler.GetQueueSize(), kTaskCount);
279
280 // 验证 FIFO 顺序
281 for (size_t i = 0; i < kTaskCount; ++i) {
282 auto* picked = scheduler.PickNext();
283 EXPECT_NE(picked, nullptr);
284 EXPECT_EQ(picked, tasks[i]);
285 }
286
287 EXPECT_EQ(scheduler.PickNext(), nullptr);
288 EXPECT_TRUE(scheduler.IsEmpty());
289
290 // 清理内存
291 for (auto* task : tasks) {
292 delete task;
293 }
294}
#define EXPECT_NE(val1, val2, msg)
Here is the call graph for this function:

◆ TEST() [8/14]

TEST ( FifoSchedulerTest  ,
MixedOperations   
)

Definition at line 209 of file fifo_scheduler_test.cpp.

209 {
210 FifoScheduler scheduler;
211
212 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
213 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
214 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
215 TaskControlBlock task4("Task4", 4, nullptr, nullptr);
216
217 // 加入 task1, task2, task3
218 scheduler.Enqueue(&task1);
219 scheduler.Enqueue(&task2);
220 scheduler.Enqueue(&task3);
221
222 // 取出 task1
223 EXPECT_EQ(scheduler.PickNext(), &task1);
224
225 // 加入 task4
226 scheduler.Enqueue(&task4);
227
228 // 移除 task3
229 scheduler.Dequeue(&task3);
230
231 // 现在队列应该是 [task2, task4]
232 EXPECT_EQ(scheduler.GetQueueSize(), 2);
233 EXPECT_EQ(scheduler.PickNext(), &task2);
234 EXPECT_EQ(scheduler.PickNext(), &task4);
235 EXPECT_EQ(scheduler.PickNext(), nullptr);
236}
Here is the call graph for this function:

◆ TEST() [9/14]

TEST ( FifoSchedulerTest  ,
OnTickHook   
)

Definition at line 297 of file fifo_scheduler_test.cpp.

297 {
298 FifoScheduler scheduler;
299
300 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
301
302 // FIFO 调度器的 OnTick 应该始终返回 false(不需要抢占)
303 EXPECT_FALSE(scheduler.OnTick(&task1));
304 EXPECT_FALSE(scheduler.OnTick(nullptr));
305}
virtual auto OnTick(TaskControlBlock *current) -> bool
Tick 更新:每个时钟中断时调用,用于更新调度器状态
Here is the call graph for this function:

◆ TEST() [10/14]

TEST ( FifoSchedulerTest  ,
OnTimeSliceExpiredHook   
)

Definition at line 308 of file fifo_scheduler_test.cpp.

308 {
309 FifoScheduler scheduler;
310
311 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
312
313 // FIFO 调度器的 OnTimeSliceExpired 应返回 true(需要重新入队)
314 EXPECT_TRUE(scheduler.OnTimeSliceExpired(&task1));
315}
virtual auto OnTimeSliceExpired(TaskControlBlock *task) -> bool
时间片耗尽处理:当任务时间片用完时调用
Here is the call graph for this function:

◆ TEST() [11/14]

TEST ( FifoSchedulerTest  ,
PriorityHooks   
)

Definition at line 318 of file fifo_scheduler_test.cpp.

318 {
319 FifoScheduler scheduler;
320
321 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
322 task1.sched_info.priority = 5;
323
324 // 这些调用不应该崩溃(即使 FIFO 不使用优先级)
325 scheduler.BoostPriority(&task1, 10);
326 scheduler.RestorePriority(&task1);
327
328 // 验证调度器仍正常工作
329 scheduler.Enqueue(&task1);
330 EXPECT_EQ(scheduler.PickNext(), &task1);
331}
virtual auto BoostPriority(TaskControlBlock *task, int new_priority) -> void
优先级提升:当任务持有资源时被更高优先级任务等待,提升其优先级
virtual auto RestorePriority(TaskControlBlock *task) -> void
优先级恢复:当任务释放资源后,恢复其原始优先级
Here is the call graph for this function:

◆ TEST() [12/14]

TEST ( FifoSchedulerTest  ,
RepeatedEnqueue   
)

Definition at line 189 of file fifo_scheduler_test.cpp.

189 {
190 FifoScheduler scheduler;
191
192 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
193
194 // 多次入队同一任务(模拟时间片用完后重新入队)
195 scheduler.Enqueue(&task1);
196 scheduler.Enqueue(&task1);
197 scheduler.Enqueue(&task1);
198
199 EXPECT_EQ(scheduler.GetQueueSize(), 3);
200
201 // 应该能三次取出同一任务
202 EXPECT_EQ(scheduler.PickNext(), &task1);
203 EXPECT_EQ(scheduler.PickNext(), &task1);
204 EXPECT_EQ(scheduler.PickNext(), &task1);
205 EXPECT_EQ(scheduler.PickNext(), nullptr);
206}
Here is the call graph for this function:

◆ TEST() [13/14]

TEST ( FifoSchedulerTest  ,
SchedulerHooks   
)

Definition at line 334 of file fifo_scheduler_test.cpp.

334 {
335 FifoScheduler scheduler;
336
337 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
338
339 // OnScheduled 和 OnPreempted 不影响队列
340 scheduler.Enqueue(&task1);
341 scheduler.OnScheduled(&task1);
342
343 EXPECT_EQ(scheduler.GetQueueSize(), 1);
344
345 auto* picked = scheduler.PickNext();
346 EXPECT_EQ(picked, &task1);
347
348 scheduler.OnPreempted(&task1);
349 auto stats = scheduler.GetStats();
350 EXPECT_EQ(stats.total_preemptions, 1);
351}
auto OnPreempted(TaskControlBlock *task) -> void override
任务被抢占时调用
virtual auto GetStats() const -> const Stats &
获取调度器统计信息
virtual auto OnScheduled(TaskControlBlock *task) -> void
任务开始运行时调用 (从 Ready 变为 Running)
Here is the call graph for this function:

◆ TEST() [14/14]

TEST ( FifoSchedulerTest  ,
Statistics   
)

Definition at line 143 of file fifo_scheduler_test.cpp.

143 {
144 FifoScheduler scheduler;
145
146 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
147 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
148
149 // 初始状态
150 auto stats = scheduler.GetStats();
151 EXPECT_EQ(stats.total_enqueues, 0);
152 EXPECT_EQ(stats.total_dequeues, 0);
153 EXPECT_EQ(stats.total_picks, 0);
154 EXPECT_EQ(stats.total_preemptions, 0);
155
156 // 测试入队统计
157 scheduler.Enqueue(&task1);
158 scheduler.Enqueue(&task2);
159 stats = scheduler.GetStats();
160 EXPECT_EQ(stats.total_enqueues, 2);
161 EXPECT_EQ(stats.total_dequeues, 0);
162 EXPECT_EQ(stats.total_picks, 0);
163
164 // 测试选择统计
165 scheduler.PickNext();
166 stats = scheduler.GetStats();
167 EXPECT_EQ(stats.total_picks, 1);
168
169 // 测试出队统计
170 scheduler.Dequeue(&task2);
171 stats = scheduler.GetStats();
172 EXPECT_EQ(stats.total_dequeues, 1);
173
174 // 测试抢占统计
175 scheduler.OnPreempted(&task1);
176 stats = scheduler.GetStats();
177 EXPECT_EQ(stats.total_preemptions, 1);
178
179 // 测试重置统计
180 scheduler.ResetStats();
181 stats = scheduler.GetStats();
182 EXPECT_EQ(stats.total_enqueues, 0);
183 EXPECT_EQ(stats.total_dequeues, 0);
184 EXPECT_EQ(stats.total_picks, 0);
185 EXPECT_EQ(stats.total_preemptions, 0);
186}
virtual auto ResetStats() -> void
重置统计信息
Here is the call graph for this function: