diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 3b579ba64..9df8024c0 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -10,6 +10,8 @@ //! `sys_` then the name of the syscall. You can find functions like this in //! submodules, and you should also implement syscalls this way. +use crate::task::TASK_MANAGER; + /// write syscall const SYSCALL_WRITE: usize = 64; /// exit syscall @@ -29,6 +31,7 @@ use process::*; /// handle syscall exception with `syscall_id` and other arguments pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { + TASK_MANAGER.add_syscall_times(syscall_id); match syscall_id { SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), SYSCALL_EXIT => sys_exit(args[0] as i32), diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index ab43bbe7d..8dd37fb11 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,6 +1,6 @@ //! Process management syscalls use crate::{ - task::{exit_current_and_run_next, suspend_current_and_run_next}, + task::{exit_current_and_run_next, suspend_current_and_run_next, find_syscall_times}, timer::get_time_us, }; @@ -38,8 +38,28 @@ pub fn sys_get_time(ts: *mut TimeVal, _tz: usize) -> isize { 0 } -// TODO: implement the syscall +/// get the information of syscall and do some change pub fn sys_trace(_trace_request: usize, _id: usize, _data: usize) -> isize { trace!("kernel: sys_trace"); - -1 + match _trace_request { + 0 => { + let ptr = _id as *const u8; + unsafe { + *ptr as isize + } + }, + 1 => { + let ptr = _id as *mut u8; + unsafe { + *ptr = (_data & 0xFF) as u8; + } + 0 + }, + 2 => { + find_syscall_times(_id) as isize + }, + _ => { + -1 + } + } } diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index c1636ef47..1c90cda28 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -54,6 +54,7 @@ lazy_static! { let mut tasks = [TaskControlBlock { task_cx: TaskContext::zero_init(), task_status: TaskStatus::UnInit, + syscall_counts: [0; 500], }; MAX_APP_NUM]; for (i, task) in tasks.iter_mut().enumerate() { task.task_cx = TaskContext::goto_restore(init_app_cx(i)); @@ -135,6 +136,20 @@ impl TaskManager { panic!("All applications completed!"); } } + + /// Get the syscall times + fn find_syscall_times(&self, _id: usize) -> usize{ + let inner = self.inner.exclusive_access(); + let current = inner.current_task; + inner.tasks[current].syscall_counts[_id] + } + + /// Add the syscall times + pub fn add_syscall_times(&self, _id: usize) { + let mut inner = TASK_MANAGER.inner.exclusive_access(); + let current = inner.current_task; + inner.tasks[current].syscall_counts[_id] += 1; + } } /// Run the first task in task list. @@ -169,3 +184,8 @@ pub fn exit_current_and_run_next() { mark_current_exited(); run_next_task(); } + +/// Return the given id syscall times +pub fn find_syscall_times(_id: usize) -> usize { + TASK_MANAGER.find_syscall_times(_id) +} diff --git a/os/src/task/switch.rs b/os/src/task/switch.rs index 3535a5ca6..0ca59590d 100644 --- a/os/src/task/switch.rs +++ b/os/src/task/switch.rs @@ -13,5 +13,8 @@ global_asm!(include_str!("switch.S")); extern "C" { /// Switch to the context of `next_task_cx_ptr`, saving the current context /// in `current_task_cx_ptr`. - pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext); + pub fn __switch( + current_task_cx_ptr: *mut TaskContext, + next_task_cx_ptr: *const TaskContext + ); } diff --git a/os/src/task/task.rs b/os/src/task/task.rs index e6580c9a9..b3ef6f125 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -9,6 +9,8 @@ pub struct TaskControlBlock { pub task_status: TaskStatus, /// The task context pub task_cx: TaskContext, + /// The task mask + pub syscall_counts: [usize; 500], } /// The status of a task