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

Go to the source code of this file.

Functions

 TEST (RoundRobinSchedulerTest, BasicEnqueueDequeue)
 
 TEST (RoundRobinSchedulerTest, RoundRobinRotation)
 
 TEST (RoundRobinSchedulerTest, DequeueSpecificTask)
 
 TEST (RoundRobinSchedulerTest, NullPointerHandling)
 
 TEST (RoundRobinSchedulerTest, RepeatedEnqueueDequeue)
 
 TEST (RoundRobinSchedulerTest, InterleavedEnqueueDequeue)
 
 TEST (RoundRobinSchedulerTest, QueueSizeAndEmpty)
 
 TEST (RoundRobinSchedulerTest, TimeSliceReset)
 
 TEST (RoundRobinSchedulerTest, Statistics)
 
 TEST (RoundRobinSchedulerTest, FairnessWithManyTasks)
 
 TEST (RoundRobinSchedulerTest, MultipleRounds)
 
 TEST (RoundRobinSchedulerTest, SingleTask)
 
 TEST (RoundRobinSchedulerTest, DequeueNonExistentTask)
 

Function Documentation

◆ TEST() [1/13]

TEST ( RoundRobinSchedulerTest  ,
BasicEnqueueDequeue   
)

Definition at line 13 of file rr_scheduler_test.cpp.

13 {
14 RoundRobinScheduler scheduler;
15
16 // 创建测试任务
17 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
18 task1.status = TaskStatus::kReady;
19
20 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
21 task2.status = TaskStatus::kReady;
22
23 // 测试空队列
24 EXPECT_EQ(scheduler.PickNext(), nullptr);
25
26 // 加入任务
27 scheduler.Enqueue(&task1);
28 scheduler.Enqueue(&task2);
29
30 // 测试 FIFO 顺序
31 EXPECT_EQ(scheduler.PickNext(), &task1);
32 EXPECT_EQ(scheduler.PickNext(), &task2);
33 EXPECT_EQ(scheduler.PickNext(), nullptr);
34}
Round-Robin 调度器
auto PickNext() -> TaskControlBlock *override
选择下一个要运行的任务
auto Enqueue(TaskControlBlock *task) -> void override
将任务加入就绪队列尾部
constexpr etl::fsm_state_id_t kReady
Definition task_fsm.hpp:15
任务控制块,管理进程/线程的核心数据结构
#define EXPECT_EQ(val1, val2, msg)
Here is the call graph for this function:

◆ TEST() [2/13]

TEST ( RoundRobinSchedulerTest  ,
DequeueNonExistentTask   
)

Definition at line 296 of file rr_scheduler_test.cpp.

296 {
297 RoundRobinScheduler scheduler;
298
299 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
300 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
301 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
302
303 scheduler.Enqueue(&task1);
304 scheduler.Enqueue(&task2);
305
306 // 尝试移除不在队列中的任务
307 scheduler.Dequeue(&task3);
308 EXPECT_EQ(scheduler.GetQueueSize(), 2);
309
310 // 验证原有任务仍在队列中
311 EXPECT_EQ(scheduler.PickNext(), &task1);
312 EXPECT_EQ(scheduler.PickNext(), &task2);
313 EXPECT_TRUE(scheduler.IsEmpty());
314}
auto Dequeue(TaskControlBlock *task) -> void override
从就绪队列中移除指定任务
auto GetQueueSize() const -> size_t override
获取就绪队列大小
auto IsEmpty() const -> bool override
判断队列是否为空
#define EXPECT_TRUE(cond, msg)
Here is the call graph for this function:

◆ TEST() [3/13]

TEST ( RoundRobinSchedulerTest  ,
DequeueSpecificTask   
)

Definition at line 66 of file rr_scheduler_test.cpp.

66 {
67 RoundRobinScheduler scheduler;
68
69 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
70 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
71 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
72
73 scheduler.Enqueue(&task1);
74 scheduler.Enqueue(&task2);
75 scheduler.Enqueue(&task3);
76
77 // 移除中间的任务
78 scheduler.Dequeue(&task2);
79
80 // 验证只剩下 task1 和 task3
81 EXPECT_EQ(scheduler.PickNext(), &task1);
82 EXPECT_EQ(scheduler.PickNext(), &task3);
83 EXPECT_EQ(scheduler.PickNext(), nullptr);
84}
Here is the call graph for this function:

◆ TEST() [4/13]

TEST ( RoundRobinSchedulerTest  ,
FairnessWithManyTasks   
)

Definition at line 230 of file rr_scheduler_test.cpp.

230 {
231 RoundRobinScheduler scheduler;
232 constexpr size_t kTaskCount = 100;
233
234 // 创建任务数组(使用动态分配)
235 kstd::vector<TaskControlBlock*> tasks;
236 for (size_t i = 0; i < kTaskCount; ++i) {
237 auto* task = new TaskControlBlock("Task", 10, nullptr, nullptr);
238 task->status = TaskStatus::kReady;
239 tasks.push_back(task);
240 scheduler.Enqueue(task);
241 }
242
243 EXPECT_EQ(scheduler.GetQueueSize(), kTaskCount);
244
245 // 验证所有任务按顺序被选中
246 for (size_t i = 0; i < kTaskCount; ++i) {
247 auto* picked = scheduler.PickNext();
248 ASSERT_NE(picked, nullptr);
249 EXPECT_EQ(picked, tasks[i]);
250 }
251
252 EXPECT_TRUE(scheduler.IsEmpty());
253
254 // 清理内存
255 for (auto* task : tasks) {
256 delete task;
257 }
258}
Here is the call graph for this function:

◆ TEST() [5/13]

TEST ( RoundRobinSchedulerTest  ,
InterleavedEnqueueDequeue   
)

Definition at line 114 of file rr_scheduler_test.cpp.

114 {
115 RoundRobinScheduler scheduler;
116
117 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
118 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
119
120 scheduler.Enqueue(&task1);
121 EXPECT_EQ(scheduler.PickNext(), &task1);
122
123 scheduler.Enqueue(&task2);
124 EXPECT_EQ(scheduler.PickNext(), &task2);
125
126 scheduler.Enqueue(&task1);
127 scheduler.Enqueue(&task2);
128 EXPECT_EQ(scheduler.PickNext(), &task1);
129 EXPECT_EQ(scheduler.PickNext(), &task2);
130}
Here is the call graph for this function:

◆ TEST() [6/13]

TEST ( RoundRobinSchedulerTest  ,
MultipleRounds   
)

Definition at line 261 of file rr_scheduler_test.cpp.

261 {
262 RoundRobinScheduler scheduler;
263
264 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
265 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
266 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
267
268 // 进行 5 轮轮转
269 for (int round = 0; round < 5; ++round) {
270 scheduler.Enqueue(&task1);
271 scheduler.Enqueue(&task2);
272 scheduler.Enqueue(&task3);
273
274 EXPECT_EQ(scheduler.PickNext(), &task1);
275 EXPECT_EQ(scheduler.PickNext(), &task2);
276 EXPECT_EQ(scheduler.PickNext(), &task3);
277 EXPECT_TRUE(scheduler.IsEmpty());
278 }
279}
Here is the call graph for this function:

◆ TEST() [7/13]

TEST ( RoundRobinSchedulerTest  ,
NullPointerHandling   
)

Definition at line 87 of file rr_scheduler_test.cpp.

87 {
88 RoundRobinScheduler scheduler;
89
90 // Enqueue 空指针应该不崩溃
91 scheduler.Enqueue(nullptr);
92 EXPECT_EQ(scheduler.PickNext(), nullptr);
93
94 // Dequeue 空指针应该不崩溃
95 scheduler.Dequeue(nullptr);
96}
Here is the call graph for this function:

◆ TEST() [8/13]

TEST ( RoundRobinSchedulerTest  ,
QueueSizeAndEmpty   
)

Definition at line 133 of file rr_scheduler_test.cpp.

133 {
134 RoundRobinScheduler scheduler;
135
136 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
137 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
138 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
139
140 // 初始状态
141 EXPECT_TRUE(scheduler.IsEmpty());
142 EXPECT_EQ(scheduler.GetQueueSize(), 0);
143
144 // 加入任务
145 scheduler.Enqueue(&task1);
146 EXPECT_FALSE(scheduler.IsEmpty());
147 EXPECT_EQ(scheduler.GetQueueSize(), 1);
148
149 scheduler.Enqueue(&task2);
150 scheduler.Enqueue(&task3);
151 EXPECT_EQ(scheduler.GetQueueSize(), 3);
152
153 // 取出任务
154 scheduler.PickNext();
155 EXPECT_EQ(scheduler.GetQueueSize(), 2);
156
157 scheduler.PickNext();
158 scheduler.PickNext();
159 EXPECT_TRUE(scheduler.IsEmpty());
160 EXPECT_EQ(scheduler.GetQueueSize(), 0);
161}
#define EXPECT_FALSE(cond, msg)
Here is the call graph for this function:

◆ TEST() [9/13]

TEST ( RoundRobinSchedulerTest  ,
RepeatedEnqueueDequeue   
)

Definition at line 99 of file rr_scheduler_test.cpp.

99 {
100 RoundRobinScheduler scheduler;
101
102 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
103
104 // 重复入队和出队
105 for (int i = 0; i < 10; ++i) {
106 scheduler.Enqueue(&task1);
107 EXPECT_EQ(scheduler.PickNext(), &task1);
108 }
109
110 EXPECT_EQ(scheduler.PickNext(), nullptr);
111}
Here is the call graph for this function:

◆ TEST() [10/13]

TEST ( RoundRobinSchedulerTest  ,
RoundRobinRotation   
)

Definition at line 37 of file rr_scheduler_test.cpp.

37 {
38 RoundRobinScheduler scheduler;
39
40 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
41 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
42 TaskControlBlock task3("Task3", 3, nullptr, nullptr);
43
44 // 加入三个任务
45 scheduler.Enqueue(&task1);
46 scheduler.Enqueue(&task2);
47 scheduler.Enqueue(&task3);
48
49 // 第一轮
50 EXPECT_EQ(scheduler.PickNext(), &task1);
51 EXPECT_EQ(scheduler.PickNext(), &task2);
52 EXPECT_EQ(scheduler.PickNext(), &task3);
53
54 // 模拟时间片用完,任务重新入队
55 scheduler.Enqueue(&task1);
56 scheduler.Enqueue(&task2);
57 scheduler.Enqueue(&task3);
58
59 // 第二轮 - 应该保持相同的顺序
60 EXPECT_EQ(scheduler.PickNext(), &task1);
61 EXPECT_EQ(scheduler.PickNext(), &task2);
62 EXPECT_EQ(scheduler.PickNext(), &task3);
63}
Here is the call graph for this function:

◆ TEST() [11/13]

TEST ( RoundRobinSchedulerTest  ,
SingleTask   
)

Definition at line 282 of file rr_scheduler_test.cpp.

282 {
283 RoundRobinScheduler scheduler;
284
285 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
286
287 scheduler.Enqueue(&task1);
288 EXPECT_EQ(scheduler.GetQueueSize(), 1);
289
290 auto* picked = scheduler.PickNext();
291 EXPECT_EQ(picked, &task1);
292 EXPECT_TRUE(scheduler.IsEmpty());
293}
Here is the call graph for this function:

◆ TEST() [12/13]

TEST ( RoundRobinSchedulerTest  ,
Statistics   
)

Definition at line 183 of file rr_scheduler_test.cpp.

183 {
184 RoundRobinScheduler scheduler;
185
186 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
187 TaskControlBlock task2("Task2", 2, nullptr, nullptr);
188
189 // 初始统计
190 auto stats = scheduler.GetStats();
191 EXPECT_EQ(stats.total_enqueues, 0);
192 EXPECT_EQ(stats.total_dequeues, 0);
193 EXPECT_EQ(stats.total_picks, 0);
194 EXPECT_EQ(stats.total_preemptions, 0);
195
196 // 测试入队统计
197 scheduler.Enqueue(&task1);
198 scheduler.Enqueue(&task2);
199 stats = scheduler.GetStats();
200 EXPECT_EQ(stats.total_enqueues, 2);
201
202 // 测试选择统计
203 scheduler.PickNext();
204 scheduler.PickNext();
205 stats = scheduler.GetStats();
206 EXPECT_EQ(stats.total_picks, 2);
207
208 // 测试出队统计
209 scheduler.Enqueue(&task1);
210 scheduler.Dequeue(&task1);
211 stats = scheduler.GetStats();
212 EXPECT_EQ(stats.total_dequeues, 1);
213
214 // 测试抢占统计
215 scheduler.OnPreempted(&task1);
216 scheduler.OnPreempted(&task2);
217 stats = scheduler.GetStats();
218 EXPECT_EQ(stats.total_preemptions, 2);
219
220 // 重置统计
221 scheduler.ResetStats();
222 stats = scheduler.GetStats();
223 EXPECT_EQ(stats.total_enqueues, 0);
224 EXPECT_EQ(stats.total_dequeues, 0);
225 EXPECT_EQ(stats.total_picks, 0);
226 EXPECT_EQ(stats.total_preemptions, 0);
227}
auto OnPreempted(TaskControlBlock *task) -> void override
任务被抢占时调用
virtual auto GetStats() const -> const Stats &
获取调度器统计信息
virtual auto ResetStats() -> void
重置统计信息
Here is the call graph for this function:

◆ TEST() [13/13]

TEST ( RoundRobinSchedulerTest  ,
TimeSliceReset   
)

Definition at line 164 of file rr_scheduler_test.cpp.

164 {
165 RoundRobinScheduler scheduler;
166
167 TaskControlBlock task1("Task1", 1, nullptr, nullptr);
168 task1.sched_info.time_slice_default = 20;
169 task1.sched_info.time_slice_remaining = 5; // 时间片快用完了
170
171 // 入队应该重置时间片
172 scheduler.Enqueue(&task1);
173 EXPECT_EQ(task1.sched_info.time_slice_remaining, 20);
174
175 // 模拟时间片耗尽
176 task1.sched_info.time_slice_remaining = 0;
177 bool should_reenqueue = scheduler.OnTimeSliceExpired(&task1);
178 EXPECT_TRUE(should_reenqueue);
179 EXPECT_EQ(task1.sched_info.time_slice_remaining, 20);
180}
auto OnTimeSliceExpired(TaskControlBlock *task) -> bool override
时间片耗尽处理
Here is the call graph for this function: