diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index e6e8f981..9e038d33 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -28,6 +28,7 @@ use fs::*; use process::*; /// handle syscall exception with `syscall_id` and other arguments pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { + super::task::increase_current_syscall_count(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 f1cd4249..e99d31d2 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,7 +1,7 @@ //! Process management syscalls use crate::{ config::MAX_SYSCALL_NUM, - task::{exit_current_and_run_next, suspend_current_and_run_next, TaskStatus}, + task::{exit_current_and_run_next, suspend_current_and_run_next, TaskStatus, get_current_task_info}, timer::get_time_us, }; @@ -51,7 +51,15 @@ pub fn sys_get_time(ts: *mut TimeVal, _tz: usize) -> isize { } /// YOUR JOB: Finish sys_task_info to pass testcases -pub fn sys_task_info(_ti: *mut TaskInfo) -> isize { - trace!("kernel: sys_task_info"); - -1 +pub fn sys_task_info(ti: *mut TaskInfo) -> isize { + if ti.is_null() { + return -1; + } + let (status, syscall_times, time) = get_current_task_info(); + unsafe { + (*ti).status = status; + (*ti).syscall_times = syscall_times;//u32类型自动复制 + (*ti).time = time; + } + 0 } diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index c1636ef4..7df1bdc0 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -14,9 +14,10 @@ mod switch; #[allow(clippy::module_inception)] mod task; -use crate::config::MAX_APP_NUM; +use crate::config::{MAX_APP_NUM,MAX_SYSCALL_NUM};//add MAX_SYSCALL_NUM use crate::loader::{get_num_app, init_app_cx}; use crate::sync::UPSafeCell; +use crate::timer::get_time_ms; use lazy_static::*; use switch::__switch; pub use task::{TaskControlBlock, TaskStatus}; @@ -54,6 +55,8 @@ lazy_static! { let mut tasks = [TaskControlBlock { task_cx: TaskContext::zero_init(), task_status: TaskStatus::UnInit, + syscall_count:[0; MAX_SYSCALL_NUM], + start_time:get_time_ms(), }; MAX_APP_NUM]; for (i, task) in tasks.iter_mut().enumerate() { task.task_cx = TaskContext::goto_restore(init_app_cx(i)); @@ -76,6 +79,19 @@ impl TaskManager { /// /// Generally, the first task in task list is an idle task (we call it zero process later). /// But in ch3, we load apps statically, so the first task is a real app. + fn increase_current_syscall_count(&self, syscall_id: usize) { + let mut inner = self.inner.exclusive_access(); + let current = inner.current_task; + inner.tasks[current].syscall_count[syscall_id] += 1; + } + fn get_current_task_info(&self) -> (TaskStatus, [u32; MAX_SYSCALL_NUM], usize) { + let inner = self.inner.exclusive_access(); + let current:usize = inner.current_task; + let task = &inner.tasks[current];//control block + let current_time = get_time_ms(); + let time = current_time - task.start_time; + (task.task_status, task.syscall_count, time) + } fn run_first_task(&self) -> ! { let mut inner = self.inner.exclusive_access(); let task0 = &mut inner.tasks[0]; @@ -169,3 +185,15 @@ pub fn exit_current_and_run_next() { mark_current_exited(); run_next_task(); } +/// increase_current_syscall_count +pub fn increase_current_syscall_count(syscall_id: usize) { + if syscall_id >= MAX_SYSCALL_NUM { + return; + } + TASK_MANAGER.increase_current_syscall_count(syscall_id); +} + +/// get_current_task_info +pub fn get_current_task_info() -> (TaskStatus, [u32; MAX_SYSCALL_NUM], usize) { + TASK_MANAGER.get_current_task_info() +} diff --git a/os/src/task/task.rs b/os/src/task/task.rs index e6580c9a..aa06cb9a 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -1,6 +1,7 @@ //! Types related to task management use super::TaskContext; +use crate::config::MAX_SYSCALL_NUM;//add MAX_SYSCALL_NUM /// The task control block (TCB) of a task. #[derive(Copy, Clone)] @@ -9,6 +10,10 @@ pub struct TaskControlBlock { pub task_status: TaskStatus, /// The task context pub task_cx: TaskContext, + /// Syscall_times + pub syscall_count: [u32; MAX_SYSCALL_NUM],//every syscall recorded + /// First yield time + pub start_time: usize, } /// The status of a task @@ -23,3 +28,4 @@ pub enum TaskStatus { /// exited Exited, } +