diff --git a/ch5/os/src/task/mod.rs b/ch5/os/src/task/mod.rs index 99c83a7..6024707 100644 --- a/ch5/os/src/task/mod.rs +++ b/ch5/os/src/task/mod.rs @@ -8,7 +8,7 @@ use crate::println; use crate::sbi::shutdown; use crate::task::context::TaskContext; use crate::task::manager::{add_task, TASK_MANAGER}; -use crate::task::processor::{schedule, take_current_task}; +use crate::task::processor::{kernel_time_start, refresh_stop_clock, schedule, take_current_task}; use crate::task::switch::__switch; use crate::timer::{get_time_ms, get_time_us}; use crate::trap::TrapContext; @@ -38,6 +38,7 @@ pub fn add_initproc() { // 挂起当前运行下一个, 需要把当前任务 从Process中 take 取出来, 然后再 push回 全局的任务管理器 pub fn suspend_current_and_run_next() { + // 必须有一个程序在运行, let task = take_current_task().unwrap(); @@ -47,6 +48,11 @@ pub fn suspend_current_and_run_next() { let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext; // Change status to Ready task_inner.task_status = TaskStatus::Ready; + + // 统计内核时间 + let kernel_time = refresh_stop_clock(); + task_inner.kernel_time += kernel_time; + drop(task_inner); // ---- release current PCB @@ -98,11 +104,18 @@ pub fn exit_current_and_run_next(exit_code: i32) { inner.children.clear(); // 子进程引用计数-1 现在又变成1了 + // 统计内核时间 + let kernel_time = refresh_stop_clock(); + inner.kernel_time += kernel_time; + println!("[kernel] user_time: {}ms, kernel_time: {}ms", inner.user_time /1000, inner.kernel_time / 1000); + + // 释放当前地址空间中, 逻辑段清空, areas->MapArea->data_frames->FrameTracker 执行析构, 过程是把areas中的物理页帧 根据 RAII还给操作系统 // 注意 页表本身占用的 三级页表的物理帧(page_table->frames), 还没有被释放, 因为我们还需要使用, 这需要父进程管理进行释放 inner.memory_set.recycle_data_pages(); drop(inner); + // 手动删除tcb, 后面这里永远不会执行了, 我们智能指针需要手动释放(这里需要给引用计数-1) drop(task); @@ -111,5 +124,7 @@ pub fn exit_current_and_run_next(exit_code: i32) { // 这个进程不会被执行了, 我们当前栈帧随便创建一个上下文就好了 let mut _unused = TaskContext::new(); + + // 输出一下 schedule(&mut _unused as *mut _); } diff --git a/ch5/os/src/task/processor.rs b/ch5/os/src/task/processor.rs index 072782b..5f9818c 100644 --- a/ch5/os/src/task/processor.rs +++ b/ch5/os/src/task/processor.rs @@ -1,12 +1,13 @@ use alloc::sync::Arc; use lazy_static::lazy_static; +use crate::println; use crate::task::context::TaskContext; use crate::task::switch::__switch; use crate::task::task::{TaskControlBlock, TaskStatus}; use crate::trap::TrapContext; use crate::sync::UPSafeCell; use crate::task::manager::{pop_task, TASK_MANAGER}; -use crate::timer::get_time_us; +use crate::timer::{get_time_ms, get_time_us}; ///维护在一个处理器上正在执行的任务, 这在ch4 中是 TaskManager做的, 现在拆分 pub struct Processor { @@ -63,11 +64,12 @@ impl Processor { } // 即将进入用户态, 把之前使用的内核时间统计 - pub fn user_time_start(&mut self) { + fn user_time_start(&mut self) { let use_clock_time = self.refresh_stop_clock(); self.current.as_ref().unwrap().inner_exclusive_access().kernel_time += use_clock_time; } - pub fn kernel_time_start(&mut self) { + + fn kernel_time_start(&mut self) { let use_clock_time = self.refresh_stop_clock(); self.current.as_ref().unwrap().inner_exclusive_access().user_time += use_clock_time; } @@ -118,6 +120,21 @@ pub fn run_tasks() { } +// 掐表函数 +pub fn refresh_stop_clock() -> usize { + PROCESSOR.exclusive_access().refresh_stop_clock() +} + +// 用户应用 进入用户态开始计时 +pub fn user_time_start(){ + PROCESSOR.exclusive_access().user_time_start(); +} + +// 用户应用 进入内核态开始计时 +pub fn kernel_time_start(){ + PROCESSOR.exclusive_access().kernel_time_start(); +} + // 取出当前正在执行的任务 pub fn take_current_task() -> Option> { PROCESSOR.exclusive_access().take_current() diff --git a/ch5/os/src/trap/mod.rs b/ch5/os/src/trap/mod.rs index ba0b249..d734ae3 100644 --- a/ch5/os/src/trap/mod.rs +++ b/ch5/os/src/trap/mod.rs @@ -11,7 +11,7 @@ use crate::syscall::syscall; use crate::task::{exit_current_and_run_next, suspend_current_and_run_next}; use crate::timer::set_next_trigger; use crate::task::manager::TASK_MANAGER; -use crate::task::processor::{current_trap_cx, current_user_token}; +use crate::task::processor::{current_task, current_trap_cx, current_user_token, kernel_time_start, user_time_start}; @@ -37,7 +37,7 @@ pub fn trap_handler() -> ! { set_kernel_trap_entry(); // 进入到了内核态, 需要把之前的用户消耗时间统计在用户时间上 - // TASK_MANAGER.kernel_time_start(); + kernel_time_start(); // 得到当前用户应用 的 trap context, 需要调用一个函数, 因为用户应用的trap context 不再内核空间, 他是在用户空间的次高地址 let cx = current_trap_cx(); @@ -80,7 +80,7 @@ pub fn trap_handler() -> ! { } } // 即将进入用户态, 把内核使用的时间统计在内核时间上 - // TASK_MANAGER.user_time_start(); + user_time_start(); trap_return() }