1use crate::loader::get_app_data_by_name;
2use crate::mm::{translated_refmut, translated_str};
3use crate::task::{
4 add_task, current_task, current_user_token, exit_current_and_run_next,
5 suspend_current_and_run_next,
6};
7use crate::timer::get_time_ms;
8use alloc::sync::Arc;
9
10pub fn sys_exit(exit_code: i32) -> ! {
11 exit_current_and_run_next(exit_code);
12 panic!("Unreachable in sys_exit!");
13}
14
15pub fn sys_yield() -> isize {
16 suspend_current_and_run_next();
17 0
18}
19
20pub fn sys_get_time() -> isize {
21 get_time_ms() as isize
22}
23
24pub fn sys_getpid() -> isize {
25 current_task().unwrap().pid.0 as isize
26}
27
28pub fn sys_fork() -> isize {
29 let current_task = current_task().unwrap();
30 let new_task = current_task.fork();
31 let new_pid = new_task.pid.0;
32 let trap_cx = new_task.inner_exclusive_access().get_trap_cx();
34 trap_cx.x[10] = 0;
37 add_task(new_task);
39 new_pid as isize
40}
41
42pub fn sys_exec(path: *const u8) -> isize {
43 let token = current_user_token();
44 let path = translated_str(token, path);
45 if let Some(data) = get_app_data_by_name(path.as_str()) {
46 let task = current_task().unwrap();
47 task.exec(data);
48 0
49 } else {
50 -1
51 }
52}
53
54pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
57 let task = current_task().unwrap();
58 let mut inner = task.inner_exclusive_access();
62 if !inner
63 .children
64 .iter()
65 .any(|p| pid == -1 || pid as usize == p.getpid())
66 {
67 return -1;
68 }
70 let pair = inner.children.iter().enumerate().find(|(_, p)| {
71 p.inner_exclusive_access().is_zombie() && (pid == -1 || pid as usize == p.getpid())
73 });
75 if let Some((idx, _)) = pair {
76 let child = inner.children.remove(idx);
77 assert_eq!(Arc::strong_count(&child), 1);
79 let found_pid = child.getpid();
80 let exit_code = child.inner_exclusive_access().exit_code;
82 *translated_refmut(inner.memory_set.token(), exit_code_ptr) = exit_code;
84 found_pid as isize
85 } else {
86 -2
87 }
88 }