| 12 | static constexpr uint64_t kMillisecondsPerSecond = 1000; |
| 13 | |
| 14 | auto TaskManager::Sleep(uint64_t ms) -> void { |
| 15 | auto& cpu_sched = GetCurrentCpuSched(); |
| 16 | |
| 17 | auto* current = GetCurrentTask(); |
| 18 | assert(current != nullptr && "Sleep: No current task to sleep"); |
| 19 | assert(current->GetStatus() == TaskStatus::kRunning && |
| 20 | "Sleep: current task status must be kRunning"); |
| 21 | |
| 22 | // 如果睡眠时间为 0,仅让出 CPU(相当于 yield) |
| 23 | if (ms == 0) { |
| 24 | Schedule(); |
| 25 | return; |
| 26 | } |
| 27 | |
| 28 | { |
| 29 | LockGuard<SpinLock> lock_guard(cpu_sched.lock); |
| 30 | |
| 31 | // 计算唤醒时间 (当前 tick + 睡眠时间) |
| 32 | uint64_t sleep_ticks = (ms * SIMPLEKERNEL_TICK) / kMillisecondsPerSecond; |
| 33 | current->sched_info.wake_tick = cpu_sched.local_tick + sleep_ticks; |
| 34 | |
| 35 | // Check capacity before transitioning FSM |
| 36 | |
| 37 | // 将任务加入睡眠队列(优先队列会自动按 wake_tick 排序) |
| 38 | if (cpu_sched.sleeping_tasks.full()) { |
| 39 | klog::Err("Sleep: sleeping_tasks full, cannot sleep task {}", |
| 40 | current->pid); |
| 41 | return; |
| 42 | } |
| 43 | current->fsm.Receive(MsgSleep{current->sched_info.wake_tick}); |
| 44 | cpu_sched.sleeping_tasks.push(current); |
| 45 | } |
| 46 | |
| 47 | // 调度到其他任务 |
| 48 | Schedule(); |
| 49 | |
| 50 | // 任务被唤醒后会从这里继续执行 |
| 51 | // 检查是否有待处理的信号(可能是信号导致了提前唤醒) |
| 52 | (void)CheckPendingSignals(); |
| 53 | } |