diff --git a/ch3/os/src/task/mod.rs b/ch3/os/src/task/mod.rs index 915a4d7..c3f6592 100644 --- a/ch3/os/src/task/mod.rs +++ b/ch3/os/src/task/mod.rs @@ -6,6 +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; mod context; mod switch; @@ -23,6 +24,9 @@ impl TaskManager { // 得到下一个需要执行的任务,的上下文 这里我们由于第一次执行, 下一个任务我们指定为0下标的任务即可 let next_task_context_ptr = { let mut inner = self.inner.exclusive_access(); + // 第一次掐表, 开始记录时间 + inner.refresh_stop_clock(); + let task_0 = &mut inner.tasks[0]; // 修改任务0的状态 task_0.task_status = TaskStatus::Running; @@ -47,16 +51,26 @@ impl TaskManager { fn mark_current_exit(&self){ let mut inner = self.inner.exclusive_access(); let current_task_id = inner.current_task_id; + let kernel_use_time = inner.refresh_stop_clock(); let current_task = &mut inner.tasks[current_task_id]; current_task.task_status = TaskStatus::Exited; + + // 统计内核时间, 并输出这个任务 花费了多少内核时间 + current_task.kernel_time += kernel_use_time; + println!("task {:?}, exit, use: {:?}ms", current_task_id, current_task.kernel_time); } // 挂起当前任务 fn mark_current_suspend(&self){ let mut inner = self.inner.exclusive_access(); let current_task_id = inner.current_task_id; + let kernel_use_time = inner.refresh_stop_clock(); let current_task = &mut inner.tasks[current_task_id]; current_task.task_status = TaskStatus::Ready; + + // 统计内核时间(因为内核进入到这里之前肯定是掐表了) + // 挂起任务A之后,这里也掐表了, 切到新的任务B, B开始执行, B在挂起的时候 也会走入到这里掐表, 顺便并得到任务A掐表到现在任务B掐表准备切换任务出去中间的时间 + current_task.kernel_time += kernel_use_time; } // 运行下一个任务 @@ -111,6 +125,18 @@ impl TaskManager { struct TaskManagerInner { tasks: [TaskControlBlock; MAX_APP_NUM], current_task_id: usize, + stop_clock_time: usize, // 记录最近一次停表时间 +} + +impl TaskManagerInner { + fn refresh_stop_clock(&mut self) -> usize { + // 上次停表的时间 + let start_time = self.stop_clock_time; + // 当前时间 + self.stop_clock_time = get_time_ms(); + // 返回 当前时间 - 上次停表时间 = 时间间距 + self.stop_clock_time - start_time + } } lazy_static!{ @@ -123,7 +149,9 @@ lazy_static!{ TaskControlBlock { task_cx: TaskContext::new(), // UnInit 这个tcb 还没用户应用填充加载 - task_status: TaskStatus::UnInit + task_status: TaskStatus::UnInit, + kernel_time: 0, + user_time: 0, }; MAX_APP_NUM ]; @@ -149,6 +177,7 @@ lazy_static!{ UPSafeCell::new(TaskManagerInner { tasks, current_task_id: 0, + stop_clock_time: 0 }) } } diff --git a/ch3/os/src/task/task.rs b/ch3/os/src/task/task.rs index e765a47..4f65803 100644 --- a/ch3/os/src/task/task.rs +++ b/ch3/os/src/task/task.rs @@ -13,6 +13,8 @@ pub enum TaskStatus { // 一个任务的主体, 用来保存或者控制一个任务所有需要的东西 #[derive(Copy, Clone)] pub struct TaskControlBlock { + pub user_time: usize, // 用户态程序用的时间 + pub kernel_time: usize, // 内核态程序所用的时间 pub task_status: TaskStatus, pub task_cx: TaskContext, } \ No newline at end of file diff --git a/ch3/user/src/bin/03sleep.rs b/ch3/user/src/bin/03sleep.rs index 8af47d4..5e002ba 100644 --- a/ch3/user/src/bin/03sleep.rs +++ b/ch3/user/src/bin/03sleep.rs @@ -11,7 +11,7 @@ fn main() -> i32 { let current_timer = sys_get_time(); let wait_for = current_timer + 3000; while sys_get_time() < wait_for { - sys_yield(); + // sys_yield(); loop太快,防止每次切换时间小于1ms, 这里注释, 但是还是不对, 模拟器的时间不准,cpu频率不对, 这个用户应用统计的怎么都不够3000ms } println!("Test sleep OK!"); 0