diff --git a/ch3/os/src/task/mod.rs b/ch3/os/src/task/mod.rs index c3f6592..b30c303 100644 --- a/ch3/os/src/task/mod.rs +++ b/ch3/os/src/task/mod.rs @@ -6,7 +6,7 @@ use crate::loader::{get_num_app, init_app_cx}; use crate::println; use crate::task::context::TaskContext; use crate::task::switch::__switch; -use crate::timer::get_time_ms; +use crate::timer::{get_time_ms, get_time_us}; mod context; mod switch; @@ -20,6 +20,24 @@ pub struct TaskManager { } impl TaskManager { + // 即将进入用户态, 把之前使用的内核时间统计 + pub fn user_time_start(&self){ + let mut inner = self.inner.exclusive_access(); + let current_task_id = inner.current_task_id; + let kernel_use_time = inner.refresh_stop_clock(); + + inner.tasks[current_task_id].kernel_time += kernel_use_time; + } + + pub fn kernel_time_start(&self){ + let mut inner = self.inner.exclusive_access(); + let current_task_id = inner.current_task_id; + let user_use_time = inner.refresh_stop_clock(); + + inner.tasks[current_task_id].user_time += user_use_time; + } + + fn run_first_task(&self){ // 得到下一个需要执行的任务,的上下文 这里我们由于第一次执行, 下一个任务我们指定为0下标的任务即可 let next_task_context_ptr = { @@ -57,7 +75,7 @@ impl TaskManager { // 统计内核时间, 并输出这个任务 花费了多少内核时间 current_task.kernel_time += kernel_use_time; - println!("task {:?}, exit, use: {:?}ms", current_task_id, current_task.kernel_time); + println!("task {:?}, exit, kernel_time: {:?}ms, user_time: {:?}ms", current_task_id, current_task.kernel_time/1000, current_task.user_time/1000); } // 挂起当前任务 @@ -133,7 +151,7 @@ impl TaskManagerInner { // 上次停表的时间 let start_time = self.stop_clock_time; // 当前时间 - self.stop_clock_time = get_time_ms(); + self.stop_clock_time = get_time_us(); // 返回 当前时间 - 上次停表时间 = 时间间距 self.stop_clock_time - start_time } diff --git a/ch3/os/src/trap/mod.rs b/ch3/os/src/trap/mod.rs index 15baee0..3b372f9 100644 --- a/ch3/os/src/trap/mod.rs +++ b/ch3/os/src/trap/mod.rs @@ -7,7 +7,7 @@ use riscv::register::scause::Interrupt; pub use context::TrapContext; use crate::println; use crate::syscall::syscall; -use crate::task::{exit_current_and_run_next, suspend_current_and_run_next}; +use crate::task::{exit_current_and_run_next, suspend_current_and_run_next, TASK_MANAGER}; use crate::timer::set_next_trigger; @@ -35,6 +35,10 @@ pub fn enable_timer_interrupt() { // 这个函数是 trap.S 中__alltraps 保存完所有寄存器在内核栈 之后会进入到这里 #[no_mangle] pub fn trap_handler(trap_context: &mut TrapContext) -> &mut TrapContext { + // 进入到了内核态, 需要把之前的用户消耗时间统计在用户时间上 + TASK_MANAGER.kernel_time_start(); + + let scause = scause::read(); // trap 发生的原因 let stval = stval::read(); // trap的附加信息 @@ -70,6 +74,8 @@ pub fn trap_handler(trap_context: &mut TrapContext) -> &mut TrapContext { ); } } + // 即将进入用户态, 把内核使用的时间统计在内核时间上 + TASK_MANAGER.user_time_start(); trap_context }