SimpleKernel 1.17.0
Loading...
Searching...
No Matches
tick_update.cpp
Go to the documentation of this file.
1
5#include "kernel_log.hpp"
6#include "task_manager.hpp"
7#include "task_messages.hpp"
8
9auto TaskManager::TickUpdate() -> void {
10 auto& cpu_sched = GetCurrentCpuSched();
11
12 bool need_preempt = false;
13
14 {
15 LockGuard<SpinLock> lock_guard(cpu_sched.lock);
16
17 // 递增本核心的 tick 计数
18 cpu_sched.local_tick++;
19
20 auto* current = GetCurrentTask();
21
22 // 唤醒睡眠队列中到时间的任务
23 while (!cpu_sched.sleeping_tasks.empty()) {
24 auto* task = cpu_sched.sleeping_tasks.top();
25
26 // 检查是否到达唤醒时间
27 if (task->sched_info.wake_tick > cpu_sched.local_tick) {
28 // sleeping_tasks 是一个 priority_queue,只需要检查队首元素
29 break;
30 }
31
32 // 唤醒任务
33 cpu_sched.sleeping_tasks.pop();
34 task->fsm.Receive(MsgWakeup{});
35
36 // 将任务重新加入对应调度器的就绪队列
37 auto* scheduler =
38 cpu_sched.schedulers[static_cast<uint8_t>(task->policy)].get();
39 if (scheduler) {
40 scheduler->Enqueue(task);
41 }
42 }
43
44 // 更新当前任务的统计信息
45 if (current && current->GetStatus() == TaskStatus::kRunning) {
46 // 更新总运行时间
47 current->sched_info.total_runtime++;
48
49 // 减少剩余时间片
50 if (current->sched_info.time_slice_remaining > 0) {
51 current->sched_info.time_slice_remaining--;
52 }
53
54 // 调用调度器的 OnTick,检查是否需要抢占
55 auto* scheduler =
56 cpu_sched.schedulers[static_cast<uint8_t>(current->policy)].get();
57
58 if (scheduler) {
59 // 调度器可能基于自己的策略决定是否抢占
60 need_preempt = scheduler->OnTick(current);
61 }
62
63 // 检查时间片是否耗尽(对于基于时间片的调度器)
64 if (!need_preempt && current->sched_info.time_slice_remaining == 0) {
65 need_preempt = true;
66 }
67 }
68 }
69
70 if (need_preempt && cpu_sched.scheduler_started) {
71 Schedule();
72 }
73}
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
auto TickUpdate() -> void
更新系统 tick
constexpr etl::fsm_state_id_t kRunning
Definition task_fsm.hpp:16
唤醒消息(无负载,用作事件)