SimpleKernel 1.17.0
Loading...
Searching...
No Matches
exit.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::Exit(int exit_code) -> void {
13 auto& cpu_sched = GetCurrentCpuSched();
14 auto* current = GetCurrentTask();
15 assert(current != nullptr && "Exit: No current task to exit");
16 assert(current->GetStatus() == TaskStatus::kRunning &&
17 "Exit: current task status must be kRunning");
18
19 {
20 LockGuard<SpinLock> lock_guard(cpu_sched.lock);
21
22 // 设置退出码
23 current->aux->exit_code = exit_code;
24
25 // 检查是否是线程组的主线程
26 bool is_group_leader = current->IsThreadGroupLeader();
27
28 // 如果是线程组的主线程,需要检查是否还有其他线程
29 if (is_group_leader && current->GetThreadGroupSize() > 1) {
31 "Exit: Thread group leader (pid={}, tgid={}) exiting, but group "
32 "still has {} threads",
33 current->pid, current->aux->tgid, current->GetThreadGroupSize());
34 }
35
36 // 从线程组中移除
37 current->LeaveThreadGroup();
38
39 // 将子进程过继给 init 进程 (仅当是进程时)
40 if (is_group_leader) {
41 ReparentChildren(current);
42 }
43
44 if (current->aux->parent_pid != 0) {
45 // 有父进程,进入僵尸状态等待回收
46 // Transition: kRunning -> kZombie
47 current->fsm.Receive(MsgExit{exit_code, true});
48
49 // 唤醒等待此进程退出的父进程
50 // 父进程会阻塞在 ChildExit 类型的资源上,数据是父进程自己的 PID
51 auto wait_resource_id =
52 ResourceId(ResourceType::kChildExit, current->aux->parent_pid);
53 Wakeup(wait_resource_id);
54
56
57 klog::Debug("Exit: pid={} waking up parent={} on resource={}",
58 current->pid, current->aux->parent_pid,
59 wait_resource_id.GetTypeName());
60 } else {
61 // 没有父进程,直接退出并释放资源
62 // Transition: kRunning -> kExited
63 current->fsm.Receive(MsgExit{exit_code, false});
64 // No parent to call wait(), reap immediately to free TCB + stack
65 ReapTask(current);
66 }
67 }
68
69 Schedule();
70
71 klog::Err("Exit: Task {} should not return from Schedule()", current->pid);
72
73 // UNREACHABLE: 任务退出后 Schedule() 不应返回
74 __builtin_unreachable();
75}
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
资源 ID
auto Exit(int exit_code=0) -> void
退出当前线程
Definition exit.cpp:12
constexpr etl::fsm_state_id_t kRunning
Definition task_fsm.hpp:16
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 级别记录日志
@ kChildExit
等待子进程退出
退出消息,携带退出码与父任务标志