15auto test_rr_basic_functionality() ->
bool {
16 klog::Info(
"Running test_rr_basic_functionality...");
33 "Queue size should be 0 for empty queue");
35 "PickNext should return nullptr for empty queue");
40 "Queue size should be 1 after enqueue");
45 "Queue size should be 3 after 3 enqueues");
48 auto* picked1 = scheduler.
PickNext();
49 EXPECT_EQ(picked1, &task1,
"First picked task should be task1");
51 auto* picked2 = scheduler.
PickNext();
52 EXPECT_EQ(picked2, &task2,
"Second picked task should be task2");
54 auto* picked3 = scheduler.
PickNext();
55 EXPECT_EQ(picked3, &task3,
"Third picked task should be task3");
58 "PickNext should return nullptr after all tasks picked");
60 klog::Info(
"test_rr_basic_functionality passed");
64auto test_rr_round_robin_behavior() ->
bool {
65 klog::Info(
"Running test_rr_round_robin_behavior...");
96 klog::Info(
"test_rr_round_robin_behavior passed");
100auto test_rr_time_slice_management() ->
bool {
101 klog::Info(
"Running test_rr_time_slice_management...");
107 task1.sched_info.time_slice_default = 20;
108 task1.sched_info.time_slice_remaining = 5;
112 EXPECT_EQ(task1.sched_info.time_slice_remaining, 20,
113 "Enqueue should reset time slice");
116 auto* picked = scheduler.
PickNext();
117 EXPECT_EQ(picked, &task1,
"Should pick task1");
120 task1.sched_info.time_slice_remaining = 0;
122 EXPECT_TRUE(should_reenqueue,
"OnTimeSliceExpired should return true for RR");
123 EXPECT_EQ(task1.sched_info.time_slice_remaining, 20,
124 "OnTimeSliceExpired should reset time slice");
126 klog::Info(
"test_rr_time_slice_management passed");
130auto test_rr_dequeue() ->
bool {
154 "Queue size should be 3 after dequeue");
159 "Queue size should be 2 after dequeue");
162 auto* picked1 = scheduler.
PickNext();
163 EXPECT_EQ(picked1, &task3,
"First remaining task should be task3");
165 auto* picked2 = scheduler.
PickNext();
166 EXPECT_EQ(picked2, &task4,
"Second remaining task should be task4");
174auto test_rr_statistics() ->
bool {
184 EXPECT_EQ(stats.total_enqueues, 0,
"Initial enqueues should be 0");
185 EXPECT_EQ(stats.total_dequeues, 0,
"Initial dequeues should be 0");
186 EXPECT_EQ(stats.total_picks, 0,
"Initial picks should be 0");
187 EXPECT_EQ(stats.total_preemptions, 0,
"Initial preemptions should be 0");
193 EXPECT_EQ(stats.total_enqueues, 2,
"Enqueues should be 2");
199 EXPECT_EQ(stats.total_picks, 2,
"Picks should be 2");
205 EXPECT_EQ(stats.total_dequeues, 1,
"Dequeues should be 1");
211 EXPECT_EQ(stats.total_preemptions, 2,
"Preemptions should be 2");
216 EXPECT_EQ(stats.total_enqueues, 0,
"Enqueues should be 0 after reset");
217 EXPECT_EQ(stats.total_dequeues, 0,
"Dequeues should be 0 after reset");
218 EXPECT_EQ(stats.total_picks, 0,
"Picks should be 0 after reset");
219 EXPECT_EQ(stats.total_preemptions, 0,
"Preemptions should be 0 after reset");
225auto test_rr_fairness() ->
bool {
229 constexpr size_t kTaskCount = 50;
233 for (
size_t i = 0; i < kTaskCount; ++i) {
240 "Queue size should match task count");
243 for (
size_t i = 0; i < kTaskCount; ++i) {
244 auto* picked = scheduler.
PickNext();
245 EXPECT_NE(picked,
nullptr,
"Picked task should not be nullptr");
246 EXPECT_EQ(picked, tasks[i],
"Task should be picked in order");
252 for (
size_t i = 0; i < kTaskCount; ++i) {
260auto test_rr_mixed_operations() ->
bool {
261 klog::Info(
"Running test_rr_mixed_operations...");
281 auto* picked1 = scheduler.
PickNext();
282 EXPECT_EQ(picked1, &task1,
"First pick should be task1");
291 auto* picked2 = scheduler.
PickNext();
292 EXPECT_EQ(picked2, &task2,
"Second pick should be task2");
294 auto* picked3 = scheduler.
PickNext();
295 EXPECT_EQ(picked3, &task4,
"Third pick should be task4");
297 auto* picked4 = scheduler.
PickNext();
298 EXPECT_EQ(picked4, &task5,
"Fourth pick should be task5");
302 klog::Info(
"test_rr_mixed_operations passed");
306auto test_rr_multiple_rounds() ->
bool {
307 klog::Info(
"Running test_rr_multiple_rounds...");
319 for (
int round = 0; round < 5; ++round) {
334auto test_rr_hooks() ->
bool {
341 task1.sched_info.priority = 5;
350 bool need_resched = scheduler.
OnTick(&task1);
351 EXPECT_EQ(need_resched,
false,
"OnTick should return false for RR");
355 EXPECT_EQ(need_requeue,
true,
"OnTimeSliceExpired should return true for RR");
359 auto* picked = scheduler.
PickNext();
360 EXPECT_EQ(picked, &task1,
"Scheduler should still work after hook calls");
366auto test_rr_robustness() ->
bool {
376 "PickNext on empty queue should return nullptr");
394auto test_rr_interleaved_operations() ->
bool {
395 klog::Info(
"Running test_rr_interleaved_operations...");
408 auto* picked1 = scheduler.
PickNext();
409 EXPECT_EQ(picked1, &task1,
"Should pick task1");
413 auto* picked2 = scheduler.
PickNext();
414 EXPECT_EQ(picked2, &task2,
"Should pick task2");
417 auto* picked3 = scheduler.
PickNext();
418 EXPECT_EQ(picked3, &task3,
"Should pick task3");
420 auto* picked4 = scheduler.
PickNext();
421 EXPECT_EQ(picked4, &task1,
"Should pick task1 again");
425 klog::Info(
"test_rr_interleaved_operations passed");
432 klog::Info(
"\n=== Round-Robin Scheduler System Tests ===\n");
434 if (!test_rr_basic_functionality()) {
438 if (!test_rr_round_robin_behavior()) {
442 if (!test_rr_time_slice_management()) {
446 if (!test_rr_dequeue()) {
450 if (!test_rr_statistics()) {
454 if (!test_rr_fairness()) {
458 if (!test_rr_mixed_operations()) {
462 if (!test_rr_multiple_rounds()) {
466 if (!test_rr_hooks()) {
470 if (!test_rr_robustness()) {
474 if (!test_rr_interleaved_operations()) {
478 klog::Info(
"=== All Round-Robin Scheduler Tests Passed ===\n");
auto OnPreempted(TaskControlBlock *task) -> void override
任务被抢占时调用
auto Dequeue(TaskControlBlock *task) -> void override
从就绪队列中移除指定任务
auto OnTimeSliceExpired(TaskControlBlock *task) -> bool override
时间片耗尽处理
auto PickNext() -> TaskControlBlock *override
选择下一个要运行的任务
auto Enqueue(TaskControlBlock *task) -> void override
将任务加入就绪队列尾部
auto GetQueueSize() const -> size_t override
获取就绪队列大小
auto IsEmpty() const -> bool override
判断队列是否为空
virtual auto OnTick(TaskControlBlock *current) -> bool
Tick 更新:每个时钟中断时调用,用于更新调度器状态
virtual auto BoostPriority(TaskControlBlock *task, int new_priority) -> void
优先级提升:当任务持有资源时被更高优先级任务等待,提升其优先级
virtual auto RestorePriority(TaskControlBlock *task) -> void
优先级恢复:当任务释放资源后,恢复其原始优先级
virtual auto GetStats() const -> const Stats &
获取调度器统计信息
virtual auto OnScheduled(TaskControlBlock *task) -> void
任务开始运行时调用 (从 Ready 变为 Running)
virtual auto ResetStats() -> void
重置统计信息
auto Receive(const etl::imessage &msg) -> void
向 FSM 发送消息
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
auto rr_scheduler_test() -> bool
#define EXPECT_TRUE(cond, msg)
#define EXPECT_NE(val1, val2, msg)
#define EXPECT_EQ(val1, val2, msg)