"腔骨龙"现在在每个用户应用退出时, 会输出用户应用占用cpu的时间

ch3
zhangxinyu 2 years ago
parent 6e7486415d
commit 85fa0baef3

@ -6,6 +6,7 @@ use crate::loader::{get_num_app, init_app_cx};
use crate::println; 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::timer::get_time_ms;
mod context; mod context;
mod switch; mod switch;
@ -23,6 +24,9 @@ impl TaskManager {
// 得到下一个需要执行的任务,的上下文 这里我们由于第一次执行, 下一个任务我们指定为0下标的任务即可 // 得到下一个需要执行的任务,的上下文 这里我们由于第一次执行, 下一个任务我们指定为0下标的任务即可
let next_task_context_ptr = { let next_task_context_ptr = {
let mut inner = self.inner.exclusive_access(); let mut inner = self.inner.exclusive_access();
// 第一次掐表, 开始记录时间
inner.refresh_stop_clock();
let task_0 = &mut inner.tasks[0]; let task_0 = &mut inner.tasks[0];
// 修改任务0的状态 // 修改任务0的状态
task_0.task_status = TaskStatus::Running; task_0.task_status = TaskStatus::Running;
@ -47,16 +51,26 @@ impl TaskManager {
fn mark_current_exit(&self){ fn mark_current_exit(&self){
let mut inner = self.inner.exclusive_access(); let mut inner = self.inner.exclusive_access();
let current_task_id = inner.current_task_id; 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]; let current_task = &mut inner.tasks[current_task_id];
current_task.task_status = TaskStatus::Exited; 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){ fn mark_current_suspend(&self){
let mut inner = self.inner.exclusive_access(); let mut inner = self.inner.exclusive_access();
let current_task_id = inner.current_task_id; 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]; let current_task = &mut inner.tasks[current_task_id];
current_task.task_status = TaskStatus::Ready; 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 { struct TaskManagerInner {
tasks: [TaskControlBlock; MAX_APP_NUM], tasks: [TaskControlBlock; MAX_APP_NUM],
current_task_id: usize, 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!{ lazy_static!{
@ -123,7 +149,9 @@ lazy_static!{
TaskControlBlock { TaskControlBlock {
task_cx: TaskContext::new(), task_cx: TaskContext::new(),
// UnInit 这个tcb 还没用户应用填充加载 // UnInit 这个tcb 还没用户应用填充加载
task_status: TaskStatus::UnInit task_status: TaskStatus::UnInit,
kernel_time: 0,
user_time: 0,
}; };
MAX_APP_NUM MAX_APP_NUM
]; ];
@ -149,6 +177,7 @@ lazy_static!{
UPSafeCell::new(TaskManagerInner { UPSafeCell::new(TaskManagerInner {
tasks, tasks,
current_task_id: 0, current_task_id: 0,
stop_clock_time: 0
}) })
} }
} }

@ -13,6 +13,8 @@ pub enum TaskStatus {
// 一个任务的主体, 用来保存或者控制一个任务所有需要的东西 // 一个任务的主体, 用来保存或者控制一个任务所有需要的东西
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct TaskControlBlock { pub struct TaskControlBlock {
pub user_time: usize, // 用户态程序用的时间
pub kernel_time: usize, // 内核态程序所用的时间
pub task_status: TaskStatus, pub task_status: TaskStatus,
pub task_cx: TaskContext, pub task_cx: TaskContext,
} }

@ -11,7 +11,7 @@ fn main() -> i32 {
let current_timer = sys_get_time(); let current_timer = sys_get_time();
let wait_for = current_timer + 3000; let wait_for = current_timer + 3000;
while sys_get_time() < wait_for { while sys_get_time() < wait_for {
sys_yield(); // sys_yield(); loop太快,防止每次切换时间小于1ms, 这里注释, 但是还是不对, 模拟器的时间不准,cpu频率不对, 这个用户应用统计的怎么都不够3000ms
} }
println!("Test sleep OK!"); println!("Test sleep OK!");
0 0

Loading…
Cancel
Save