| 48 | } |
| 49 | |
| 50 | void test_exit_normal(void* /*arg*/) { |
| 51 | klog::Info("=== Exit Normal Test ==="); |
| 52 | |
| 53 | bool passed = true; |
| 54 | |
| 55 | // 1. 创建 TCB 并检查初始状态不是终止态 |
| 56 | auto* task = new TaskControlBlock("ExitNormal", 10, nullptr, nullptr); |
| 57 | task->pid = local_pid_counter.fetch_add(1); |
| 58 | task->aux->tgid = task->pid; |
| 59 | task->aux->parent_pid = 1; |
| 60 | |
| 61 | if (task->GetStatus() == TaskStatus::kExited || |
| 62 | task->GetStatus() == TaskStatus::kZombie) { |
| 63 | klog::Err("test_exit_normal: FAIL — fresh TCB already in terminal state"); |
| 64 | passed = false; |
| 65 | } |
| 66 | |
| 67 | // 2. exit_code 默认应为 0 |
| 68 | if (task->aux->exit_code != 0) { |
| 69 | klog::Err("test_exit_normal: FAIL — default exit_code != 0 (got {})", |
| 70 | task->aux->exit_code); |
| 71 | passed = false; |
| 72 | } |
| 73 | |
| 74 | // 3. 创建有实际工作函数的任务,等待其完成后通过 flag 验证执行路径 |
| 75 | std::atomic<int> work_flag{0}; |
| 76 | auto worker = kstd::make_unique<TaskControlBlock>( |
| 77 | "ExitNormalWorker", 10, normal_work, reinterpret_cast<void*>(&work_flag)); |
| 78 | TaskManagerSingleton::instance().AddTask(std::move(worker)); |
| 79 | |
| 80 | // 等待 worker 运行完毕(最多 500ms) |
| 81 | int timeout = 10; |
| 82 | while (timeout > 0 && work_flag.load() == 0) { |
| 83 | (void)sys_sleep(50); |
| 84 | timeout--; |
| 85 | } |
| 86 | |
| 87 | if (work_flag.load() != 1) { |
| 88 | klog::Err("test_exit_normal: FAIL — worker did not complete"); |
| 89 | passed = false; |
| 90 | } else { |
| 91 | klog::Info("test_exit_normal: worker completed successfully"); |
| 92 | } |
| 93 | |
| 94 | // 4. 向 task 写入退出信息并验证读回一致 |
| 95 | task->aux->exit_code = 0; |
| 96 | task->fsm.Receive(MsgSchedule{}); // kUnInit -> kReady |
| 97 | task->fsm.Receive(MsgSchedule{}); // kReady -> kRunning |
| 98 | task->fsm.Receive(MsgExit{0, true}); // kRunning -> kZombie |
| 99 | if (task->aux->exit_code != 0 || task->GetStatus() != TaskStatus::kZombie) { |
| 100 | klog::Err("test_exit_normal: FAIL — TCB field write-back mismatch"); |
| 101 | passed = false; |
| 102 | } |
| 103 | |
| 104 | if (passed) { |
| 105 | klog::Info("Exit Normal Test: PASSED"); |
| 106 | } else { |
| 107 | klog::Err("Exit Normal Test: FAILED"); |