SimpleKernel 1.17.0
Loading...
Searching...
No Matches
wakeup.cpp
Go to the documentation of this file.
1
5#include <cassert>
6
7#include "kernel_log.hpp"
8#include "resource_id.hpp"
9#include "task_manager.hpp"
10#include "task_messages.hpp"
11
12auto TaskManager::Wakeup(ResourceId resource_id) -> void {
13 auto& cpu_sched = GetCurrentCpuSched();
14
15 LockGuard<SpinLock> lock_guard(cpu_sched.lock);
16
17 // 查找等待该资源的任务列表
18 auto it = cpu_sched.blocked_tasks.find(resource_id);
19
20 if (it == cpu_sched.blocked_tasks.end()) {
21 // 没有任务等待该资源
22 klog::Debug("Wakeup: No tasks waiting on resource={}, data={:#x}",
23 resource_id.GetTypeName(),
24 static_cast<uint64_t>(resource_id.GetData()));
25 return;
26 }
27
28 // 唤醒所有等待该资源的任务
29 auto& waiting_tasks = it->second;
30 size_t wakeup_count = 0;
31
32 while (!waiting_tasks.empty()) {
33 auto* task = waiting_tasks.front();
34 waiting_tasks.pop_front();
35
36 assert(task->GetStatus() == TaskStatus::kBlocked &&
37 "Wakeup: task status must be kBlocked");
38 assert(task->aux->blocked_on == resource_id &&
39 "Wakeup: task blocked_on must match resource_id");
40
41 // 将任务标记为就绪
42 task->fsm.Receive(MsgWakeup{});
43 task->aux->blocked_on = ResourceId{};
44
45 // 将任务重新加入对应调度器的就绪队列
46 auto* scheduler =
47 cpu_sched.schedulers[static_cast<uint8_t>(task->policy)].get();
48 assert(scheduler != nullptr && "Wakeup: scheduler must not be null");
49 scheduler->Enqueue(task);
50 wakeup_count++;
51 }
52
53 // 移除空的资源队列
54 cpu_sched.blocked_tasks.erase(resource_id);
55
56 klog::Debug("Wakeup: Woke up {} tasks from resource={}, data={:#x}",
57 wakeup_count, resource_id.GetTypeName(),
58 static_cast<uint64_t>(resource_id.GetData()));
59}
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
资源 ID
auto Wakeup(ResourceId resource_id) -> void
唤醒等待指定资源的所有任务
Definition wakeup.cpp:12
constexpr etl::fsm_state_id_t kBlocked
Definition task_fsm.hpp:18
auto Debug(etl::format_string< Args... > fmt, Args &&... args) -> void
以 DEBUG 级别记录日志(SIMPLEKERNEL_MIN_LOG_LEVEL > 0 时编译期消除)
唤醒消息(无负载,用作事件)