| 92 | } |
| 93 | |
| 94 | auto TaskManager::AddTask(etl::unique_ptr<TaskControlBlock> task) -> void { |
| 95 | assert(task.get() != nullptr && "AddTask: task must not be null"); |
| 96 | assert(task->GetStatus() == TaskStatus::kUnInit && |
| 97 | "AddTask: task status must be kUnInit"); |
| 98 | // 分配 PID |
| 99 | if (task->pid == 0) { |
| 100 | task->pid = AllocatePid(); |
| 101 | } |
| 102 | |
| 103 | // 如果 tgid 未设置,则将其设为自己的 pid (单线程进程或线程组的主线程) |
| 104 | if (task->aux->tgid == 0) { |
| 105 | task->aux->tgid = task->pid; |
| 106 | } |
| 107 | |
| 108 | auto* task_ptr = task.get(); |
| 109 | Pid pid = task_ptr->pid; |
| 110 | |
| 111 | // 加入全局任务表 |
| 112 | { |
| 113 | LockGuard lock_guard{task_table_lock_}; |
| 114 | if (task_table_.full()) { |
| 115 | klog::Err("AddTask: task_table_ full, cannot add task (pid={})", pid); |
| 116 | return; |
| 117 | } |
| 118 | task_table_[pid] = std::move(task); |
| 119 | } |
| 120 | |
| 121 | // 设置任务状态为 kReady |
| 122 | // Transition: kUnInit -> kReady |
| 123 | task_ptr->fsm.Receive(MsgSchedule{}); |
| 124 | |
| 125 | // 简单的负载均衡:如果指定了亲和性,放入对应核心,否则放入当前核心 |
| 126 | // 更复杂的逻辑可以是:寻找最空闲的核心 |
| 127 | size_t target_core = cpu_io::GetCurrentCoreId(); |
| 128 | |
| 129 | if (task_ptr->aux->cpu_affinity.value() != UINT64_MAX) { |
| 130 | // 寻找第一个允许的核心 |
| 131 | for (size_t core_id = 0; core_id < SIMPLEKERNEL_MAX_CORE_COUNT; ++core_id) { |
| 132 | if (task_ptr->aux->cpu_affinity.value() & (1UL << core_id)) { |
| 133 | target_core = core_id; |
| 134 | break; |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | auto& cpu_sched = cpu_schedulers_[target_core]; |
| 140 | |
| 141 | { |
| 142 | LockGuard<SpinLock> lock_guard(cpu_sched.lock); |
| 143 | if (task_ptr->policy < SchedPolicy::kPolicyCount) { |
| 144 | if (cpu_sched.schedulers[static_cast<uint8_t>(task_ptr->policy)]) { |
| 145 | cpu_sched.schedulers[static_cast<uint8_t>(task_ptr->policy)]->Enqueue( |
| 146 | task_ptr); |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | // 如果是当前核心,且添加了比当前任务优先级更高的任务,触发抢占 |