| 11 | #include "virtual_memory.hpp" |
| 12 | |
| 13 | auto TaskManager::Clone(uint64_t flags, void* user_stack, int* parent_tid, |
| 14 | int* child_tid, void* tls, |
| 15 | cpu_io::TrapContext& parent_context) -> Expected<Pid> { |
| 16 | auto* parent = GetCurrentTask(); |
| 17 | if (!parent) { |
| 18 | klog::Err("Clone: No current task"); |
| 19 | return std::unexpected(Error(ErrorCode::kTaskNoCurrentTask)); |
| 20 | } |
| 21 | |
| 22 | // 验证克隆标志的合法性 |
| 23 | // 如果设置了 kCloneThread,必须同时设置 kCloneVm, kCloneFiles, kCloneSighand |
| 24 | if ((flags & clone_flag::kThread) && |
| 25 | (!(flags & clone_flag::kVm) || !(flags & clone_flag::kFiles) || |
| 26 | !(flags & clone_flag::kSighand))) { |
| 27 | klog::Warn( |
| 28 | "Clone: kCloneThread requires kCloneVm, kCloneFiles, kCloneSighand"); |
| 29 | // 自动补全必需的标志 |
| 30 | flags |= (clone_flag::kVm | clone_flag::kFiles | clone_flag::kSighand); |
| 31 | } |
| 32 | |
| 33 | // 分配新的 PID |
| 34 | Pid new_pid = AllocatePid(); |
| 35 | if (new_pid == 0) { |
| 36 | klog::Err("Clone: Failed to allocate PID"); |
| 37 | return std::unexpected(Error(ErrorCode::kTaskPidAllocationFailed)); |
| 38 | } |
| 39 | |
| 40 | // 创建子任务控制块 |
| 41 | auto child_ptr = kstd::make_unique<TaskControlBlock>(); |
| 42 | if (!child_ptr) { |
| 43 | klog::Err("Clone: Failed to allocate child task"); |
| 44 | return std::unexpected(Error(ErrorCode::kTaskAllocationFailed)); |
| 45 | } |
| 46 | auto* child = child_ptr.get(); |
| 47 | // Default ctor leaves FSM in set_states-but-not-started state. |
| 48 | // Start it so get_state_id() returns kUnInit instead of deref null. |
| 49 | child->fsm.Start(); |
| 50 | |
| 51 | // 基本字段设置 |
| 52 | child->pid = new_pid; |
| 53 | child->name = parent->name; |
| 54 | child->policy = parent->policy; |
| 55 | child->sched_info = parent->sched_info; |
| 56 | |
| 57 | // 设置父进程 ID |
| 58 | if (flags & clone_flag::kParent) { |
| 59 | // 保持与父进程相同的父进程 |
| 60 | child->aux->parent_pid = parent->aux->parent_pid; |
| 61 | } else { |
| 62 | child->aux->parent_pid = parent->pid; |
| 63 | } |
| 64 | |
| 65 | // 处理线程组 ID (TGID) |
| 66 | if (flags & clone_flag::kThread) { |
| 67 | // 创建线程: 共享线程组 |
| 68 | child->aux->tgid = parent->aux->tgid; |
| 69 | child->aux->pgid = parent->aux->pgid; |
| 70 | child->aux->sid = parent->aux->sid; |
no test coverage detected