22#include "kstd_cstring"
31auto IdleThread(
void*) ->
void {
41 auto& cpu_sched = cpu_schedulers_[
core_id];
47 kstd::make_unique<FifoScheduler>();
49 kstd::make_unique<RoundRobinScheduler>();
51 kstd::make_unique<IdleScheduler>();
56 cpu_data.sched_data = &cpu_sched;
61 auto boot_task_ptr = kstd::make_unique<TaskControlBlock>(
66 auto* boot_task = boot_task_ptr.release();
72 cpu_data.running_task = boot_task;
75 auto idle_task_ptr = kstd::make_unique<TaskControlBlock>(
80 auto*
idle_task = idle_task_ptr.release();
95 assert(task.get() !=
nullptr &&
"AddTask: task must not be null");
97 "AddTask: task status must be kUnInit");
100 task->pid = AllocatePid();
104 if (task->aux->tgid == 0) {
105 task->aux->tgid = task->pid;
108 auto* task_ptr = task.get();
109 Pid pid = task_ptr->pid;
114 if (task_table_.full()) {
115 klog::Err(
"AddTask: task_table_ full, cannot add task (pid={})", pid);
118 task_table_[pid] = std::move(task);
129 if (task_ptr->aux->cpu_affinity.value() != UINT64_MAX) {
132 if (task_ptr->aux->cpu_affinity.value() & (1UL <<
core_id)) {
139 auto& cpu_sched = cpu_schedulers_[target_core];
144 if (cpu_sched.schedulers[
static_cast<uint8_t
>(task_ptr->policy)]) {
145 cpu_sched.schedulers[
static_cast<uint8_t
>(task_ptr->policy)]->Enqueue(
156 if (current == cpu_data.idle_task ||
172 return pid_allocator_.fetch_add(1);
177 auto it = task_table_.find(pid);
178 return (it != task_table_.end()) ? it->second.get() :
nullptr;
194 klog::Warn(
"ReapTask: Task {} is not in zombie/exited state", task->pid);
204 task_table_.erase(pid);
207 klog::Debug(
"ReapTask: Task {} resources freed", pid);
217 static constexpr Pid kInitPid = 1;
222 for (
auto& [pid, task] : task_table_) {
223 if (task && task->aux->parent_pid == parent->pid) {
225 task->aux->parent_pid = kInitPid;
226 klog::Debug(
"ReparentChildren: Task {} reparented to init (PID {})",
227 task->pid, kInitPid);
235 -> etl::vector<TaskControlBlock*, kernel::config::kMaxReadyTasks> {
236 etl::vector<TaskControlBlock*, kernel::config::kMaxReadyTasks> result;
241 for (
auto& [pid, task] : task_table_) {
242 if (task && task->aux->tgid == tgid) {
243 result.push_back(task.get());
252 klog::Debug(
"SignalThreadGroup: tgid={}, signal={} (not implemented)", tgid,
auto Receive(const etl::imessage &msg) -> void
向 FSM 发送消息
auto AddTask(etl::unique_ptr< TaskControlBlock > task) -> void
添加任务(接管所有权)
auto ReapTask(TaskControlBlock *task) -> void
回收僵尸进程资源
auto ReparentChildren(TaskControlBlock *parent) -> void
将孤儿进程过继给 init 进程
auto AllocatePid() -> size_t
分配新的 PID
auto InitCurrentCore() -> void
初始化 per cpu 的调度数据,创建 idle 线程
auto Balance() -> void
负载均衡 (空闲 core 窃取任务)
auto FindTask(Pid pid) -> TaskControlBlock *
按 PID 查找任务
auto SignalThreadGroup(Pid tgid, int signal) -> void
向线程组中的所有线程发送信号
auto GetThreadGroup(Pid tgid) -> etl::vector< TaskControlBlock *, kernel::config::kMaxReadyTasks >
获取线程组的所有线程
constexpr etl::fsm_state_id_t kExited
constexpr etl::fsm_state_id_t kUnInit
constexpr etl::fsm_state_id_t kZombie
auto GetCurrentCoreId() -> size_t
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
auto Debug(etl::format_string< Args... > fmt, Args &&... args) -> void
以 DEBUG 级别记录日志(SIMPLEKERNEL_MIN_LOG_LEVEL > 0 时编译期消除)
auto Warn(etl::format_string< Args... > fmt, Args &&... args) -> void
以 WARN 级别记录日志
static __always_inline auto GetCurrentCore() -> PerCpu &
获取当前核心的 PerCpu 数据
TaskControlBlock * idle_task
空闲任务
int priority
优先级 (数字越小优先级越高)