现在统计内核态和用户态的时间

ch5
zhangxinyu 2 years ago
parent a0a0167af0
commit bef8691ce0

@ -8,7 +8,7 @@ use crate::println;
use crate::sbi::shutdown; use crate::sbi::shutdown;
use crate::task::context::TaskContext; use crate::task::context::TaskContext;
use crate::task::manager::{add_task, TASK_MANAGER}; 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::task::switch::__switch;
use crate::timer::{get_time_ms, get_time_us}; use crate::timer::{get_time_ms, get_time_us};
use crate::trap::TrapContext; use crate::trap::TrapContext;
@ -38,6 +38,7 @@ pub fn add_initproc() {
// 挂起当前运行下一个, 需要把当前任务 从Process中 take 取出来, 然后再 push回 全局的任务管理器 // 挂起当前运行下一个, 需要把当前任务 从Process中 take 取出来, 然后再 push回 全局的任务管理器
pub fn suspend_current_and_run_next() { pub fn suspend_current_and_run_next() {
// 必须有一个程序在运行, // 必须有一个程序在运行,
let task = take_current_task().unwrap(); 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; let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext;
// Change status to Ready // Change status to Ready
task_inner.task_status = TaskStatus::Ready; task_inner.task_status = TaskStatus::Ready;
// 统计内核时间
let kernel_time = refresh_stop_clock();
task_inner.kernel_time += kernel_time;
drop(task_inner); drop(task_inner);
// ---- release current PCB // ---- release current PCB
@ -98,11 +104,18 @@ pub fn exit_current_and_run_next(exit_code: i32) {
inner.children.clear(); // 子进程引用计数-1 现在又变成1了 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还给操作系统 // 释放当前地址空间中, 逻辑段清空, areas->MapArea->data_frames->FrameTracker 执行析构, 过程是把areas中的物理页帧 根据 RAII还给操作系统
// 注意 页表本身占用的 三级页表的物理帧(page_table->frames), 还没有被释放, 因为我们还需要使用, 这需要父进程管理进行释放 // 注意 页表本身占用的 三级页表的物理帧(page_table->frames), 还没有被释放, 因为我们还需要使用, 这需要父进程管理进行释放
inner.memory_set.recycle_data_pages(); inner.memory_set.recycle_data_pages();
drop(inner); drop(inner);
// 手动删除tcb, 后面这里永远不会执行了, 我们智能指针需要手动释放(这里需要给引用计数-1) // 手动删除tcb, 后面这里永远不会执行了, 我们智能指针需要手动释放(这里需要给引用计数-1)
drop(task); drop(task);
@ -111,5 +124,7 @@ pub fn exit_current_and_run_next(exit_code: i32) {
// 这个进程不会被执行了, 我们当前栈帧随便创建一个上下文就好了 // 这个进程不会被执行了, 我们当前栈帧随便创建一个上下文就好了
let mut _unused = TaskContext::new(); let mut _unused = TaskContext::new();
// 输出一下
schedule(&mut _unused as *mut _); schedule(&mut _unused as *mut _);
} }

@ -1,12 +1,13 @@
use alloc::sync::Arc; use alloc::sync::Arc;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use crate::println;
use crate::task::context::TaskContext; use crate::task::context::TaskContext;
use crate::task::switch::__switch; use crate::task::switch::__switch;
use crate::task::task::{TaskControlBlock, TaskStatus}; use crate::task::task::{TaskControlBlock, TaskStatus};
use crate::trap::TrapContext; use crate::trap::TrapContext;
use crate::sync::UPSafeCell; use crate::sync::UPSafeCell;
use crate::task::manager::{pop_task, TASK_MANAGER}; 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做的, 现在拆分 ///维护在一个处理器上正在执行的任务, 这在ch4 中是 TaskManager做的, 现在拆分
pub struct Processor { 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(); let use_clock_time = self.refresh_stop_clock();
self.current.as_ref().unwrap().inner_exclusive_access().kernel_time += use_clock_time; 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(); let use_clock_time = self.refresh_stop_clock();
self.current.as_ref().unwrap().inner_exclusive_access().user_time += use_clock_time; 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<Arc<TaskControlBlock>> { pub fn take_current_task() -> Option<Arc<TaskControlBlock>> {
PROCESSOR.exclusive_access().take_current() PROCESSOR.exclusive_access().take_current()

@ -11,7 +11,7 @@ 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};
use crate::timer::set_next_trigger; use crate::timer::set_next_trigger;
use crate::task::manager::TASK_MANAGER; 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(); set_kernel_trap_entry();
// 进入到了内核态, 需要把之前的用户消耗时间统计在用户时间上 // 进入到了内核态, 需要把之前的用户消耗时间统计在用户时间上
// TASK_MANAGER.kernel_time_start(); kernel_time_start();
// 得到当前用户应用 的 trap context, 需要调用一个函数, 因为用户应用的trap context 不再内核空间, 他是在用户空间的次高地址 // 得到当前用户应用 的 trap context, 需要调用一个函数, 因为用户应用的trap context 不再内核空间, 他是在用户空间的次高地址
let cx = current_trap_cx(); let cx = current_trap_cx();
@ -80,7 +80,7 @@ pub fn trap_handler() -> ! {
} }
} }
// 即将进入用户态, 把内核使用的时间统计在内核时间上 // 即将进入用户态, 把内核使用的时间统计在内核时间上
// TASK_MANAGER.user_time_start(); user_time_start();
trap_return() trap_return()
} }

Loading…
Cancel
Save