If there is not a child process whose pid is same as given, return -1. Else if there is a child process but it is still running, return -2.
(pid: isize, exit_code_ptr: *mut i32)
| 70 | /// If there is not a child process whose pid is same as given, return -1. |
| 71 | /// Else if there is a child process but it is still running, return -2. |
| 72 | pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize { |
| 73 | let process = current_process(); |
| 74 | // find a child process |
| 75 | |
| 76 | let mut inner = process.inner_exclusive_access(); |
| 77 | if !inner |
| 78 | .children |
| 79 | .iter() |
| 80 | .any(|p| pid == -1 || pid as usize == p.getpid()) |
| 81 | { |
| 82 | return -1; |
| 83 | // ---- release current PCB |
| 84 | } |
| 85 | let pair = inner.children.iter().enumerate().find(|(_, p)| { |
| 86 | // ++++ temporarily access child PCB exclusively |
| 87 | p.inner_exclusive_access().is_zombie && (pid == -1 || pid as usize == p.getpid()) |
| 88 | // ++++ release child PCB |
| 89 | }); |
| 90 | if let Some((idx, _)) = pair { |
| 91 | let child = inner.children.remove(idx); |
| 92 | // confirm that child will be deallocated after being removed from children list |
| 93 | assert_eq!(Arc::strong_count(&child), 1); |
| 94 | let found_pid = child.getpid(); |
| 95 | // ++++ temporarily access child PCB exclusively |
| 96 | let exit_code = child.inner_exclusive_access().exit_code; |
| 97 | // ++++ release child PCB |
| 98 | *translated_refmut(inner.memory_set.token(), exit_code_ptr) = exit_code; |
| 99 | found_pid as isize |
| 100 | } else { |
| 101 | -2 |
| 102 | } |
| 103 | // ---- release current PCB automatically |
| 104 | } |
| 105 | |
| 106 | pub fn sys_kill(pid: usize, signal: u32) -> isize { |
| 107 | if let Some(process) = pid2process(pid) { |
no test coverage detected