MCPcopy Create free account
hub / github.com/chyyuu/os_kernel_lab / fork

Method fork

os/src/task/process.rs:188–253  ·  view source on GitHub ↗

Only support processes with a single thread.

(self: &Arc<Self>)

Source from the content-addressed store, hash-verified

186
187 /// Only support processes with a single thread.
188 pub fn fork(self: &Arc<Self>) -> Arc<Self> {
189 let mut parent = self.inner_exclusive_access();
190 assert_eq!(parent.thread_count(), 1);
191 // clone parent's memory_set completely including trampoline/ustacks/trap_cxs
192 let memory_set = MemorySet::from_existed_user(&parent.memory_set);
193 // alloc a pid
194 let pid = pid_alloc();
195 // copy fd table
196 let mut new_fd_table: Vec<Option<Arc<dyn File + Send + Sync>>> = Vec::new();
197 for fd in parent.fd_table.iter() {
198 if let Some(file) = fd {
199 new_fd_table.push(Some(file.clone()));
200 } else {
201 new_fd_table.push(None);
202 }
203 }
204 // create child process pcb
205 let child = Arc::new(Self {
206 pid,
207 inner: unsafe {
208 UPIntrFreeCell::new(ProcessControlBlockInner {
209 is_zombie: false,
210 memory_set,
211 parent: Some(Arc::downgrade(self)),
212 children: Vec::new(),
213 exit_code: 0,
214 fd_table: new_fd_table,
215 signals: SignalFlags::empty(),
216 tasks: Vec::new(),
217 task_res_allocator: RecycleAllocator::new(),
218 mutex_list: Vec::new(),
219 semaphore_list: Vec::new(),
220 condvar_list: Vec::new(),
221 })
222 },
223 });
224 // add child
225 parent.children.push(Arc::clone(&child));
226 // create main thread of child process
227 let task = Arc::new(TaskControlBlock::new(
228 Arc::clone(&child),
229 parent
230 .get_task(0)
231 .inner_exclusive_access()
232 .res
233 .as_ref()
234 .unwrap()
235 .ustack_base(),
236 // here we do not allocate trap_cx or ustack again
237 // but mention that we allocate a new kstack here
238 false,
239 ));
240 // attach task to child process
241 let mut child_inner = child.inner_exclusive_access();
242 child_inner.tasks.push(Some(Arc::clone(&task)));
243 drop(child_inner);
244 // modify kstack_top in trap_cx of this thread
245 let task_inner = task.inner_exclusive_access();

Callers 1

sys_forkFunction · 0.80

Calls 12

pid_allocFunction · 0.85
cloneFunction · 0.85
dropFunction · 0.85
insert_into_pid2processFunction · 0.85
add_taskFunction · 0.85
ustack_baseMethod · 0.80
get_taskMethod · 0.80
get_trap_cxMethod · 0.80
get_topMethod · 0.80
getpidMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected