| 37 | } // namespace |
| 38 | |
| 39 | auto TaskManager::InitCurrentCore() -> void { |
| 40 | auto core_id = cpu_io::GetCurrentCoreId(); |
| 41 | auto& cpu_sched = cpu_schedulers_[core_id]; |
| 42 | |
| 43 | LockGuard lock_guard{cpu_sched.lock}; |
| 44 | |
| 45 | if (!cpu_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)]) { |
| 46 | cpu_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kRealTime)] = |
| 47 | kstd::make_unique<FifoScheduler>(); |
| 48 | cpu_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kNormal)] = |
| 49 | kstd::make_unique<RoundRobinScheduler>(); |
| 50 | cpu_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kIdle)] = |
| 51 | kstd::make_unique<IdleScheduler>(); |
| 52 | } |
| 53 | |
| 54 | // 关联 PerCpu |
| 55 | auto& cpu_data = per_cpu::GetCurrentCore(); |
| 56 | cpu_data.sched_data = &cpu_sched; |
| 57 | |
| 58 | // 创建 boot 任务作为当前执行上下文的占位符 |
| 59 | // 首次 Schedule(): |
| 60 | // current(boot_task) != next(idle_task) -> switch_to -> idle_thread |
| 61 | auto boot_task_ptr = kstd::make_unique<TaskControlBlock>( |
| 62 | "Boot", |
| 63 | std::numeric_limits< |
| 64 | decltype(TaskControlBlock::SchedInfo::priority)>::max(), |
| 65 | nullptr, nullptr); |
| 66 | auto* boot_task = boot_task_ptr.release(); |
| 67 | // kUnInit -> kReady |
| 68 | boot_task->fsm.Receive(MsgSchedule{}); |
| 69 | // kReady -> kRunning |
| 70 | boot_task->fsm.Receive(MsgSchedule{}); |
| 71 | boot_task->policy = SchedPolicy::kIdle; |
| 72 | cpu_data.running_task = boot_task; |
| 73 | |
| 74 | // 创建独立的 Idle 线程 |
| 75 | auto idle_task_ptr = kstd::make_unique<TaskControlBlock>( |
| 76 | "Idle", |
| 77 | std::numeric_limits< |
| 78 | decltype(TaskControlBlock::SchedInfo::priority)>::max(), |
| 79 | IdleThread, nullptr); |
| 80 | auto* idle_task = idle_task_ptr.release(); |
| 81 | // kUnInit -> kReady |
| 82 | idle_task->fsm.Receive(MsgSchedule{}); |
| 83 | idle_task->policy = SchedPolicy::kIdle; |
| 84 | |
| 85 | // 将 idle 任务加入 Idle 调度器 |
| 86 | if (cpu_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kIdle)]) { |
| 87 | cpu_sched.schedulers[static_cast<uint8_t>(SchedPolicy::kIdle)]->Enqueue( |
| 88 | idle_task); |
| 89 | } |
| 90 | |
| 91 | cpu_data.idle_task = idle_task; |
| 92 | } |
| 93 | |
| 94 | auto TaskManager::AddTask(etl::unique_ptr<TaskControlBlock> task) -> void { |
| 95 | assert(task.get() != nullptr && "AddTask: task must not be null"); |
no test coverage detected