| 34 | } |
| 35 | |
| 36 | auto TaskManager::Schedule() -> void { |
| 37 | auto& cpu_sched = GetCurrentCpuSched(); |
| 38 | cpu_sched.lock.Lock().or_else([](auto&& err) { |
| 39 | klog::Err("Schedule: Failed to acquire lock: {}", err.message()); |
| 40 | while (true) { |
| 41 | cpu_io::Pause(); |
| 42 | } |
| 43 | return Expected<void>{}; |
| 44 | }); |
| 45 | |
| 46 | cpu_sched.scheduler_started = true; |
| 47 | |
| 48 | auto* current = GetCurrentTask(); |
| 49 | assert(current != nullptr && "Schedule: No current task to schedule"); |
| 50 | |
| 51 | // 处理当前任务状态 |
| 52 | if (current->GetStatus() == TaskStatus::kRunning) { |
| 53 | // 将当前任务标记为就绪并重新入队(如果它还能运行) |
| 54 | current->fsm.Receive(MsgYield{}); |
| 55 | auto* scheduler = |
| 56 | cpu_sched.schedulers[static_cast<uint8_t>(current->policy)].get(); |
| 57 | |
| 58 | if (scheduler) { |
| 59 | scheduler->OnPreempted(current); |
| 60 | // 调度器决定如何处理被抢占的任务 |
| 61 | // 大多数情况下需要重新入队,除非是特殊策略 |
| 62 | if (scheduler->OnTimeSliceExpired(current)) { |
| 63 | scheduler->Enqueue(current); |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | // 选择下一个任务 (按策略优先级: RealTime > Normal > Idle) |
| 69 | TaskControlBlock* next = nullptr; |
| 70 | for (auto& scheduler : cpu_sched.schedulers) { |
| 71 | if (scheduler && !scheduler->IsEmpty()) { |
| 72 | next = scheduler->PickNext(); |
| 73 | if (next) { |
| 74 | break; |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | // 如果没有任务可运行 |
| 80 | if (!next) { |
| 81 | // 如果当前任务仍然可以运行,继续运行它 |
| 82 | if (current->GetStatus() == TaskStatus::kReady) { |
| 83 | next = current; |
| 84 | } else { |
| 85 | // 否则统计空闲时间并返回 |
| 86 | cpu_sched.idle_time++; |
| 87 | cpu_sched.lock.UnLock().or_else([](auto&& err) { |
| 88 | klog::Err("Schedule: Failed to release lock: {}", err.message()); |
| 89 | while (true) { |
| 90 | cpu_io::Pause(); |
| 91 | } |
| 92 | return Expected<void>{}; |
| 93 | }); |
no test coverage detected