15 {
17 if (!parent) {
20 }
21
22
23
28 "Clone: kCloneThread requires kCloneVm, kCloneFiles, kCloneSighand");
29
31 }
32
33
35 if (new_pid == 0) {
36 klog::Err(
"Clone: Failed to allocate PID");
38 }
39
40
41 auto child_ptr = kstd::make_unique<TaskControlBlock>();
42 if (!child_ptr) {
43 klog::Err(
"Clone: Failed to allocate child task");
45 }
46 auto* child = child_ptr.get();
47
48
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
59
60 child->aux->parent_pid = parent->aux->parent_pid;
61 } else {
62 child->aux->parent_pid = parent->pid;
63 }
64
65
67
68 child->aux->tgid = parent->aux->tgid;
69 child->aux->pgid = parent->aux->pgid;
70 child->aux->sid = parent->aux->sid;
71
72
73 if (parent->IsThreadGroupLeader()) {
74 child->JoinThreadGroup(parent);
75 } else {
76
78 if (leader) {
79 child->JoinThreadGroup(leader);
80 } else {
81 klog::Warn(
"Clone: Thread group leader not found for tgid={}",
82 parent->aux->tgid);
83 }
84 }
85 } else {
86
87
88 child->aux->tgid = new_pid;
89 child->aux->pgid = parent->aux->pgid;
90 child->aux->sid = parent->aux->sid;
91 }
92
93
95
96
99 klog::Debug(
"Clone: sharing file descriptor table (not implemented)");
100 } else {
101 klog::Debug(
"Clone: copying file descriptor table (not implemented)");
102 }
103
104
107 klog::Debug(
"Clone: sharing signal handlers (not implemented)");
108 } else {
109 klog::Debug(
"Clone: copying signal handlers (not implemented)");
110 }
111
112
115 klog::Debug(
"Clone: sharing filesystem info (not implemented)");
116 } else {
117 klog::Debug(
"Clone: copying filesystem info (not implemented)");
118 }
119
120
122
123 child->page_table = parent->page_table;
125 reinterpret_cast<uintptr_t>(child->page_table));
126 } else {
127
128 if (parent->page_table) {
129
130 auto result = VirtualMemorySingleton::instance().ClonePageDirectory(
131 parent->page_table, true);
132 if (!result.has_value()) {
133 klog::Err(
"Clone: Failed to clone page table: {}",
134 result.error().message());
135
136
138 VirtualMemorySingleton::instance().DestroyPageDirectory(
139 child->page_table, false);
140 child->page_table = nullptr;
141 }
143 }
144 child->page_table = reinterpret_cast<uint64_t*>(result.value());
145 klog::Debug(
"Clone: cloned page table from {:#x} to {:#x}",
146 reinterpret_cast<uintptr_t>(parent->page_table),
147 reinterpret_cast<uintptr_t>(child->page_table));
148 } else {
149
150 child->page_table = nullptr;
151 }
152 }
153
154
155 child->kernel_stack = static_cast<uint8_t*>(
158 if (!child->kernel_stack) {
159 klog::Err(
"Clone: Failed to allocate kernel stack");
160
162 VirtualMemorySingleton::instance().DestroyPageDirectory(child->page_table,
163 false);
164 child->page_table = nullptr;
165 }
167 }
168
169
170 kstd::memset(child->kernel_stack, 0,
172
173
177 kstd::memcpy(child->trap_context_ptr, &parent_context,
179
180
181 if (user_stack) {
182 child->trap_context_ptr->UserStackPointer() =
183 reinterpret_cast<uint64_t>(user_stack);
184 }
185
186
187 if (tls) {
188 child->trap_context_ptr->ThreadPointer() = reinterpret_cast<uint64_t>(tls);
189 }
190
191
193
194 child->trap_context_ptr->ReturnValue() = 0;
195
196
197 if (parent_tid) {
198 *parent_tid = new_pid;
199 }
200 if (child_tid) {
201 *child_tid = new_pid;
202 }
203
204
206
207
211 "Clone: created {} - parent={}, child={}, tgid={}, vm={}, flags={:#x}",
212 clone_type, parent->pid, new_pid, child->aux->tgid, vm_type,
213 static_cast<uint64_t>(flags));
214 return new_pid;
215}
auto AddTask(etl::unique_ptr< TaskControlBlock > task) -> void
添加任务(接管所有权)
auto FindTask(Pid pid) -> TaskControlBlock *
按 PID 查找任务
@ kTaskPidAllocationFailed
@ kTaskKernelStackAllocationFailed
constexpr uint64_t kFiles
共享文件描述符表
constexpr uint64_t kSighand
共享信号处理器
constexpr uint64_t kParent
保持相同父进程
constexpr uint64_t kThread
同一线程组
constexpr uint64_t kFs
共享文件系统信息
constexpr uint64_t kVm
共享地址空间
static constexpr size_t kPageSize
auto Warn(etl::format_string< Args... > fmt, Args &&... args) -> void
以 WARN 级别记录日志
void * aligned_alloc(size_t alignment, size_t size)
static constexpr size_t kDefaultKernelStackSize
默认内核栈大小 (16 KB)
__always_inline uint64_t & ReturnValue()
etl::flags< uint64_t, clone_flag::kAllMask > CloneFlags
克隆标志位