15auto test_idle_basic_functionality() ->
bool {
16 klog::Info(
"Running test_idle_basic_functionality...");
21 EXPECT_EQ(scheduler.
name[0],
'I',
"Scheduler name should start with I");
30 "Queue size should be 0 for empty queue");
32 "PickNext should return nullptr for empty queue");
37 "Queue size should be 1 after enqueue");
46 "Scheduler should NOT be empty after PickNext");
48 "Queue size should still be 1 after PickNext");
51 auto* picked2 = scheduler.
PickNext();
53 "Second PickNext should return same idle task");
55 "Queue size should still be 1 after multiple PickNext");
57 klog::Info(
"test_idle_basic_functionality passed");
61auto test_idle_pick_next_does_not_remove() ->
bool {
62 klog::Info(
"Running test_idle_pick_next_does_not_remove...");
70 constexpr int kPickCount = 10;
71 for (
int i = 0; i < kPickCount; ++i) {
75 "Queue size should remain 1 after PickNext");
78 klog::Info(
"test_idle_pick_next_does_not_remove passed");
82auto test_idle_enqueue_dequeue() ->
bool {
83 klog::Info(
"Running test_idle_enqueue_dequeue...");
96 "Queue size should be 0 after dequeue");
99 "PickNext should return nullptr after dequeue");
104 "Queue size should be 1 after re-enqueue");
106 "PickNext should return idle task after re-enqueue");
108 klog::Info(
"test_idle_enqueue_dequeue passed");
112auto test_idle_on_tick_always_false() ->
bool {
113 klog::Info(
"Running test_idle_on_tick_always_false...");
121 constexpr int kTickCount = 10;
122 for (
int i = 0; i < kTickCount; ++i) {
124 EXPECT_FALSE(need_resched,
"OnTick should always return false for idle");
127 klog::Info(
"test_idle_on_tick_always_false passed");
131auto test_idle_on_time_slice_expired_always_false() ->
bool {
132 klog::Info(
"Running test_idle_on_time_slice_expired_always_false...");
141 EXPECT_FALSE(need_requeue,
"OnTimeSliceExpired should return false for idle");
143 klog::Info(
"test_idle_on_time_slice_expired_always_false passed");
147auto test_idle_statistics() ->
bool {
148 klog::Info(
"Running test_idle_statistics...");
156 EXPECT_EQ(stats.total_enqueues, 0,
"Initial enqueues should be 0");
157 EXPECT_EQ(stats.total_dequeues, 0,
"Initial dequeues should be 0");
158 EXPECT_EQ(stats.total_picks, 0,
"Initial picks should be 0");
159 EXPECT_EQ(stats.total_preemptions, 0,
"Initial preemptions should be 0");
164 EXPECT_EQ(stats.total_enqueues, 1,
"Enqueues should be 1");
170 EXPECT_EQ(stats.total_picks, 2,
"Picks should be 2");
175 EXPECT_EQ(stats.total_dequeues, 1,
"Dequeues should be 1");
180 EXPECT_EQ(stats.total_preemptions, 1,
"Preemptions should be 1");
185 EXPECT_EQ(stats.total_enqueues, 0,
"Enqueues should be 0 after reset");
186 EXPECT_EQ(stats.total_dequeues, 0,
"Dequeues should be 0 after reset");
187 EXPECT_EQ(stats.total_picks, 0,
"Picks should be 0 after reset");
188 EXPECT_EQ(stats.total_preemptions, 0,
"Preemptions should be 0 after reset");
194auto test_idle_dequeue_wrong_task() ->
bool {
195 klog::Info(
"Running test_idle_dequeue_wrong_task...");
205 scheduler.
Dequeue(&other_task);
207 "Queue size should still be 1 after dequeue of wrong task");
209 "Idle task should still be present");
211 klog::Info(
"test_idle_dequeue_wrong_task passed");
215auto test_idle_robustness() ->
bool {
216 klog::Info(
"Running test_idle_robustness...");
224 "PickNext on empty queue should return nullptr");
236 scheduler.
Enqueue(&idle_task2);
238 "New idle task should replace old one");
247 klog::Info(
"\n=== Idle Scheduler System Tests ===\n");
249 if (!test_idle_basic_functionality()) {
253 if (!test_idle_pick_next_does_not_remove()) {
257 if (!test_idle_enqueue_dequeue()) {
261 if (!test_idle_on_tick_always_false()) {
265 if (!test_idle_on_time_slice_expired_always_false()) {
269 if (!test_idle_statistics()) {
273 if (!test_idle_dequeue_wrong_task()) {
277 if (!test_idle_robustness()) {
281 klog::Info(
"=== All Idle Scheduler Tests Passed ===\n");
auto Dequeue(TaskControlBlock *task) -> void override
从队列中移除任务
auto Enqueue(TaskControlBlock *task) -> void override
将 idle 任务加入队列
auto GetQueueSize() const -> size_t override
获取队列大小
auto OnTimeSliceExpired(TaskControlBlock *task) -> bool override
时间片耗尽处理(idle 任务不使用时间片)
auto OnTick(TaskControlBlock *current) -> bool override
Tick 更新(idle 任务不需要时间片管理)
auto IsEmpty() const -> bool override
判断队列是否为空
auto PickNext() -> TaskControlBlock *override
选择下一个要运行的任务(返回 idle 任务)
auto OnPreempted(TaskControlBlock *task) -> void override
任务被抢占时的处理(idle 任务不需要特殊处理)
virtual auto GetStats() const -> const Stats &
获取调度器统计信息
virtual auto ResetStats() -> void
重置统计信息
auto Receive(const etl::imessage &msg) -> void
向 FSM 发送消息
auto idle_scheduler_test() -> bool
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
TaskControlBlock * idle_task
空闲任务
#define EXPECT_TRUE(cond, msg)
#define EXPECT_FALSE(cond, msg)
#define EXPECT_EQ(val1, val2, msg)