SimpleKernel 1.17.0
Loading...
Searching...
No Matches
task_manager.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <cpu_io.h>
8#include <etl/list.h>
9#include <etl/memory.h>
10#include <etl/priority_queue.h>
11#include <etl/singleton.h>
12#include <etl/unordered_map.h>
13#include <etl/vector.h>
14
15#include <MPMCQueue.hpp>
16#include <array>
17#include <cstddef>
18#include <cstdint>
19
20#include "expected.hpp"
21#include "interrupt_base.h"
22#include "kernel_config.hpp"
23#include "kstd_memory"
24#include "per_cpu.hpp"
25#include "resource_id.hpp"
26#include "scheduler_base.hpp"
27#include "spinlock.hpp"
29
34 SpinLock lock{"sched_lock"};
35
37 std::array<etl::unique_ptr<SchedulerBase>,
38 static_cast<uint8_t>(SchedPolicy::kPolicyCount)>
40
42 etl::priority_queue<
44 etl::vector<TaskControlBlock*, kernel::config::kMaxSleepingTasks>,
47
49 etl::unordered_map<
51 etl::list<TaskControlBlock*, kernel::config::kMaxBlockedPerGroup>,
55
57 uint64_t local_tick{0};
58
60 uint64_t idle_time{0};
61
63 uint64_t total_schedules{0};
64
66 bool scheduler_started{false};
67
70 CpuSchedData() = default;
71 CpuSchedData(const CpuSchedData&) = delete;
73 auto operator=(const CpuSchedData&) -> CpuSchedData& = delete;
74 auto operator=(CpuSchedData&&) -> CpuSchedData& = delete;
75 ~CpuSchedData() = default;
77};
78
85 public:
89 auto InitCurrentCore() -> void;
90
99 auto AddTask(etl::unique_ptr<TaskControlBlock> task) -> void;
100
110 auto Schedule() -> void;
111
116 [[nodiscard]] auto GetCurrentTask() const -> TaskControlBlock* {
117 return per_cpu::GetCurrentCore().running_task;
118 }
119
123 auto TickUpdate() -> void;
124
129 auto Sleep(uint64_t ms) -> void;
130
135 [[noreturn]] auto Exit(int exit_code = 0) -> void;
136
141 auto Block(ResourceId resource_id) -> void;
142
148 auto Wakeup(ResourceId resource_id) -> void;
149
165 [[nodiscard]] auto Clone(uint64_t flags, void* user_stack, int* parent_tid,
166 int* child_tid, void* tls,
167 cpu_io::TrapContext& parent_context)
168 -> Expected<Pid>;
169
178 [[nodiscard]] auto Wait(Pid pid, int* status, bool no_hang = false,
179 bool untraced = false) -> Expected<Pid>;
180
186 [[nodiscard]] auto FindTask(Pid pid) -> TaskControlBlock*;
187
190 TaskManager() = default;
191 TaskManager(const TaskManager&) = delete;
193 auto operator=(const TaskManager&) -> TaskManager& = delete;
194 auto operator=(TaskManager&&) -> TaskManager& = delete;
195 ~TaskManager();
197
198 private:
200 static constexpr size_t kInterruptQueueCapacity = 256;
201
206 using WorkHandler = void (*)(InterruptWork*);
207
209 uint64_t interrupt_no{0};
213 uint64_t timestamp{0};
214
217 };
218
221 mpmc_queue::MPMCQueue<InterruptWork, kInterruptQueueCapacity>;
222
224 std::array<CpuSchedData, SIMPLEKERNEL_MAX_CORE_COUNT> cpu_schedulers_{};
225
227 SpinLock task_table_lock_{"task_table_lock"};
228 etl::unordered_map<Pid, etl::unique_ptr<TaskControlBlock>,
232
234 SpinLock interrupt_threads_lock_{"interrupt_threads_lock"};
236 etl::unordered_map<uint64_t, TaskControlBlock*,
241 etl::unordered_map<uint64_t, InterruptWorkQueue*,
245
247 std::atomic<size_t> pid_allocator_{1};
248
253 [[nodiscard]] auto AllocatePid() -> size_t;
254
258 auto Balance() -> void;
259
264 [[nodiscard]] auto GetCurrentCpuSched() -> CpuSchedData& {
266 }
267
274 auto GetThreadGroup(Pid tgid)
275 -> etl::vector<TaskControlBlock*, kernel::config::kMaxReadyTasks>;
276
283 auto SignalThreadGroup(Pid tgid, int signal) -> void;
284
290 auto ReapTask(TaskControlBlock* task) -> void;
291
297 auto ReparentChildren(TaskControlBlock* parent) -> void;
298};
299
300using TaskManagerSingleton = etl::singleton<TaskManager>;
资源 ID
自旋锁
Definition spinlock.hpp:27
任务管理器
std::atomic< size_t > pid_allocator_
PID 分配器
auto Block(ResourceId resource_id) -> void
阻塞当前任务
Definition block.cpp:12
auto Schedule() -> void
调度函数 选择下一个任务并切换上下文
Definition schedule.cpp:26
auto GetCurrentTask() const -> TaskControlBlock *
获取当前任务
auto Exit(int exit_code=0) -> void
退出当前线程
Definition exit.cpp:12
auto AddTask(etl::unique_ptr< TaskControlBlock > task) -> void
添加任务(接管所有权)
auto ReapTask(TaskControlBlock *task) -> void
回收僵尸进程资源
auto operator=(TaskManager &&) -> TaskManager &=delete
auto GetCurrentCpuSched() -> CpuSchedData &
获取当前核心的调度数据
auto ReparentChildren(TaskControlBlock *parent) -> void
将孤儿进程过继给 init 进程
auto operator=(const TaskManager &) -> TaskManager &=delete
etl::unordered_map< uint64_t, TaskControlBlock *, kernel::config::kMaxInterruptThreads, kernel::config::kMaxInterruptThreadsBuckets > interrupt_threads_
中断号 -> 中断线程映射
static constexpr size_t kInterruptQueueCapacity
中断工作队列容量
auto Wakeup(ResourceId resource_id) -> void
唤醒等待指定资源的所有任务
Definition wakeup.cpp:12
etl::unordered_map< uint64_t, InterruptWorkQueue *, kernel::config::kMaxInterruptThreads, kernel::config::kMaxInterruptThreadsBuckets > interrupt_work_queues_
中断号 -> 工作队列映射
auto AllocatePid() -> size_t
分配新的 PID
SpinLock interrupt_threads_lock_
中断线程相关数据保护锁
auto InitCurrentCore() -> void
初始化 per cpu 的调度数据,创建 idle 线程
TaskManager(const TaskManager &)=delete
etl::unordered_map< Pid, etl::unique_ptr< TaskControlBlock >, kernel::config::kMaxTasks, kernel::config::kMaxTasksBuckets > task_table_
auto Sleep(uint64_t ms) -> void
线程睡眠
Definition sleep.cpp:14
std::array< CpuSchedData, SIMPLEKERNEL_MAX_CORE_COUNT > cpu_schedulers_
每个核心的调度数据
mpmc_queue::MPMCQueue< InterruptWork, kInterruptQueueCapacity > InterruptWorkQueue
中断工作队列
TaskManager()=default
auto Balance() -> void
负载均衡 (空闲 core 窃取任务)
auto TickUpdate() -> void
更新系统 tick
auto Clone(uint64_t flags, void *user_stack, int *parent_tid, int *child_tid, void *tls, cpu_io::TrapContext &parent_context) -> Expected< Pid >
克隆当前任务 (fork/clone 系统调用)
Definition clone.cpp:13
TaskManager(TaskManager &&)=delete
auto Wait(Pid pid, int *status, bool no_hang=false, bool untraced=false) -> Expected< Pid >
等待子进程退出
Definition wait.cpp:13
auto FindTask(Pid pid) -> TaskControlBlock *
按 PID 查找任务
auto SignalThreadGroup(Pid tgid, int signal) -> void
向线程组中的所有线程发送信号
SpinLock task_table_lock_
全局任务表 (PID -> TCB 映射)
auto GetThreadGroup(Pid tgid) -> etl::vector< TaskControlBlock *, kernel::config::kMaxReadyTasks >
获取线程组的所有线程
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto GetCurrentCoreId() -> size_t
Definition cpu_io.h:26
constexpr size_t kMaxBlockedGroups
阻塞队列:最大资源组数(blocked_tasks 的 map 容量)
constexpr size_t kMaxSleepingTasks
每个 CPU 的最大睡眠任务数(sleeping_tasks 容量)
constexpr size_t kMaxTasks
全局最大任务数(task_table_ 容量)
constexpr size_t kMaxInterruptThreadsBuckets
中断线程 map 桶数
constexpr size_t kMaxInterruptThreads
最大中断线程数
constexpr size_t kMaxTasksBuckets
task_table_ 桶数(建议 = 2 × kMaxTasks)
constexpr size_t kMaxBlockedGroupsBuckets
阻塞队列:map 桶数
static __always_inline auto GetCurrentCore() -> PerCpu &
获取当前核心的 PerCpu 数据
Definition per_cpu.hpp:55
每个核心的调度数据 (RunQueue)
auto operator=(const CpuSchedData &) -> CpuSchedData &=delete
CpuSchedData(const CpuSchedData &)=delete
std::array< etl::unique_ptr< SchedulerBase >, static_cast< uint8_t >(SchedPolicy::kPolicyCount)> schedulers
调度器数组 (按策略索引)
etl::priority_queue< TaskControlBlock *, kernel::config::kMaxSleepingTasks, etl::vector< TaskControlBlock *, kernel::config::kMaxSleepingTasks >, TaskControlBlock::WakeTickCompare > sleeping_tasks
睡眠队列 (优先队列,按唤醒时间排序)
auto operator=(CpuSchedData &&) -> CpuSchedData &=delete
uint64_t idle_time
本核心的空闲时间 (单位: ticks)
bool scheduler_started
Schedule() 是否已被显式调用
~CpuSchedData()=default
uint64_t total_schedules
本核心的总调度次数
CpuSchedData(CpuSchedData &&)=delete
etl::unordered_map< ResourceId, etl::list< TaskControlBlock *, kernel::config::kMaxBlockedPerGroup >, kernel::config::kMaxBlockedGroups, kernel::config::kMaxBlockedGroupsBuckets > blocked_tasks
阻塞队列 (按资源 ID 分组)
uint64_t local_tick
Per-CPU tick 计数 (每个核心独立计时)
CpuSchedData()=default
任务唤醒时间比较函数,时间越早优先级越高
任务控制块,管理进程/线程的核心数据结构
中断线程处理结构体
uint64_t timestamp
时间戳
cpu_io::TrapContext * data
中断上下文
uint64_t interrupt_no
中断号
void(*)(InterruptWork *) WorkHandler
WorkHandler handler
工作处理函数
@ kPolicyCount
策略数量
size_t Pid
进程 ID 类型
etl::singleton< TaskManager > TaskManagerSingleton