use alloc::sync::Arc;
use crate::{
config::MAX_SYSCALL_NUM,
loader::get_app_data_by_name,
mm::{translated_refmut, translated_str},
task::{
add_task, current_task, current_user_token, exit_current_and_run_next,
suspend_current_and_run_next, TaskStatus,
},
};
#[repr(C)]
#[derive(Debug)]
pub struct TimeVal {
pub sec: usize,
pub usec: usize,
}
#[allow(dead_code)]
pub struct TaskInfo {
status: TaskStatus,
syscall_times: [u32; MAX_SYSCALL_NUM],
time: usize,
}
pub fn sys_exit(exit_code: i32) -> ! {
trace!("kernel:pid[{}] sys_exit", current_task().unwrap().pid.0);
exit_current_and_run_next(exit_code);
panic!("Unreachable in sys_exit!");
}
pub fn sys_yield() -> isize {
trace!("kernel:pid[{}] sys_yield", current_task().unwrap().pid.0);
suspend_current_and_run_next();
0
}
pub fn sys_getpid() -> isize {
trace!("kernel: sys_getpid pid:{}", current_task().unwrap().pid.0);
current_task().unwrap().pid.0 as isize
}
pub fn sys_fork() -> isize {
trace!("kernel:pid[{}] sys_fork", current_task().unwrap().pid.0);
let current_task = current_task().unwrap();
let new_task = current_task.fork();
let new_pid = new_task.pid.0;
let trap_cx = new_task.inner_exclusive_access().get_trap_cx();
trap_cx.x[10] = 0;
add_task(new_task);
new_pid as isize
}
pub fn sys_exec(path: *const u8) -> isize {
trace!("kernel:pid[{}] sys_exec", current_task().unwrap().pid.0);
let token = current_user_token();
let path = translated_str(token, path);
if let Some(data) = get_app_data_by_name(path.as_str()) {
let task = current_task().unwrap();
task.exec(data);
0
} else {
-1
}
}
pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
trace!("kernel::pid[{}] sys_waitpid [{}]", current_task().unwrap().pid.0, pid);
let task = current_task().unwrap();
let mut inner = task.inner_exclusive_access();
if !inner
.children
.iter()
.any(|p| pid == -1 || pid as usize == p.getpid())
{
return -1;
}
let pair = inner.children.iter().enumerate().find(|(_, p)| {
p.inner_exclusive_access().is_zombie() && (pid == -1 || pid as usize == p.getpid())
});
if let Some((idx, _)) = pair {
let child = inner.children.remove(idx);
assert_eq!(Arc::strong_count(&child), 1);
let found_pid = child.getpid();
let exit_code = child.inner_exclusive_access().exit_code;
*translated_refmut(inner.memory_set.token(), exit_code_ptr) = exit_code;
found_pid as isize
} else {
-2
}
}
pub fn sys_get_time(_ts: *mut TimeVal, _tz: usize) -> isize {
trace!(
"kernel:pid[{}] sys_get_time NOT IMPLEMENTED",
current_task().unwrap().pid.0
);
-1
}
pub fn sys_task_info(_ti: *mut TaskInfo) -> isize {
trace!(
"kernel:pid[{}] sys_task_info NOT IMPLEMENTED",
current_task().unwrap().pid.0
);
-1
}
pub fn sys_mmap(_start: usize, _len: usize, _port: usize) -> isize {
trace!(
"kernel:pid[{}] sys_mmap NOT IMPLEMENTED",
current_task().unwrap().pid.0
);
-1
}
pub fn sys_munmap(_start: usize, _len: usize) -> isize {
trace!(
"kernel:pid[{}] sys_munmap NOT IMPLEMENTED",
current_task().unwrap().pid.0
);
-1
}
pub fn sys_sbrk(size: i32) -> isize {
trace!("kernel:pid[{}] sys_sbrk", current_task().unwrap().pid.0);
if let Some(old_brk) = current_task().unwrap().change_program_brk(size) {
old_brk as isize
} else {
-1
}
}
pub fn sys_spawn(_path: *const u8) -> isize {
trace!(
"kernel:pid[{}] sys_spawn NOT IMPLEMENTED",
current_task().unwrap().pid.0
);
-1
}
pub fn sys_set_priority(_prio: isize) -> isize {
trace!(
"kernel:pid[{}] sys_set_priority NOT IMPLEMENTED",
current_task().unwrap().pid.0
);
-1
}