|
|
|
@ -4,7 +4,7 @@ mod task;
|
|
|
|
|
|
|
|
|
|
use crate::loader::{get_num_app, get_app_data};
|
|
|
|
|
use crate::trap::TrapContext;
|
|
|
|
|
use core::cell::RefCell;
|
|
|
|
|
use crate::sync::UPSafeCell;
|
|
|
|
|
use lazy_static::*;
|
|
|
|
|
use switch::__switch;
|
|
|
|
|
use task::{TaskControlBlock, TaskStatus};
|
|
|
|
@ -14,7 +14,7 @@ pub use context::TaskContext;
|
|
|
|
|
|
|
|
|
|
pub struct TaskManager {
|
|
|
|
|
num_app: usize,
|
|
|
|
|
inner: RefCell<TaskManagerInner>,
|
|
|
|
|
inner: UPSafeCell<TaskManagerInner>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct TaskManagerInner {
|
|
|
|
@ -22,8 +22,6 @@ struct TaskManagerInner {
|
|
|
|
|
current_task: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe impl Sync for TaskManager {}
|
|
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
|
pub static ref TASK_MANAGER: TaskManager = {
|
|
|
|
|
println!("init TASK_MANAGER");
|
|
|
|
@ -38,41 +36,41 @@ lazy_static! {
|
|
|
|
|
}
|
|
|
|
|
TaskManager {
|
|
|
|
|
num_app,
|
|
|
|
|
inner: RefCell::new(TaskManagerInner {
|
|
|
|
|
inner: unsafe { UPSafeCell::new(TaskManagerInner {
|
|
|
|
|
tasks,
|
|
|
|
|
current_task: 0,
|
|
|
|
|
}),
|
|
|
|
|
})},
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl TaskManager {
|
|
|
|
|
fn run_first_task(&self) {
|
|
|
|
|
self.inner.borrow_mut().tasks[0].task_status = TaskStatus::Running;
|
|
|
|
|
let next_task_cx_ptr2 = self.inner.borrow().tasks[0].get_task_cx_ptr2();
|
|
|
|
|
let _unused: usize = 0;
|
|
|
|
|
let next_task = &mut self.inner.upsafe_access().tasks[0];
|
|
|
|
|
next_task.task_status = TaskStatus::Running;
|
|
|
|
|
let next_task_cx_ptr = &next_task.task_cx as *const TaskContext;
|
|
|
|
|
drop(next_task);
|
|
|
|
|
let mut _unused = TaskContext::zero_init();
|
|
|
|
|
unsafe {
|
|
|
|
|
__switch(
|
|
|
|
|
&_unused as *const _,
|
|
|
|
|
next_task_cx_ptr2,
|
|
|
|
|
&mut _unused as *mut _,
|
|
|
|
|
next_task_cx_ptr,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn mark_current_suspended(&self) {
|
|
|
|
|
let mut inner = self.inner.borrow_mut();
|
|
|
|
|
let current = inner.current_task;
|
|
|
|
|
inner.tasks[current].task_status = TaskStatus::Ready;
|
|
|
|
|
let inner = self.inner.upsafe_access();
|
|
|
|
|
inner.tasks[inner.current_task].task_status = TaskStatus::Ready;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn mark_current_exited(&self) {
|
|
|
|
|
let mut inner = self.inner.borrow_mut();
|
|
|
|
|
let current = inner.current_task;
|
|
|
|
|
inner.tasks[current].task_status = TaskStatus::Exited;
|
|
|
|
|
let inner = self.inner.upsafe_access();
|
|
|
|
|
inner.tasks[inner.current_task].task_status = TaskStatus::Exited;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn find_next_task(&self) -> Option<usize> {
|
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
|
let inner = self.inner.upsafe_access();
|
|
|
|
|
let current = inner.current_task;
|
|
|
|
|
(current + 1..current + self.num_app + 1)
|
|
|
|
|
.map(|id| id % self.num_app)
|
|
|
|
@ -82,30 +80,28 @@ impl TaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_current_token(&self) -> usize {
|
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
|
let current = inner.current_task;
|
|
|
|
|
inner.tasks[current].get_user_token()
|
|
|
|
|
let inner = self.inner.upsafe_access();
|
|
|
|
|
inner.tasks[inner.current_task].get_user_token()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_current_trap_cx(&self) -> &mut TrapContext {
|
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
|
let current = inner.current_task;
|
|
|
|
|
inner.tasks[current].get_trap_cx()
|
|
|
|
|
let inner = self.inner.upsafe_access();
|
|
|
|
|
inner.tasks[inner.current_task].get_trap_cx()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn run_next_task(&self) {
|
|
|
|
|
if let Some(next) = self.find_next_task() {
|
|
|
|
|
let mut inner = self.inner.borrow_mut();
|
|
|
|
|
let mut inner = self.inner.upsafe_access();
|
|
|
|
|
let current = inner.current_task;
|
|
|
|
|
inner.tasks[next].task_status = TaskStatus::Running;
|
|
|
|
|
inner.current_task = next;
|
|
|
|
|
let current_task_cx_ptr2 = inner.tasks[current].get_task_cx_ptr2();
|
|
|
|
|
let next_task_cx_ptr2 = inner.tasks[next].get_task_cx_ptr2();
|
|
|
|
|
core::mem::drop(inner);
|
|
|
|
|
let current_task_cx_ptr = &mut inner.tasks[current].task_cx as *mut TaskContext;
|
|
|
|
|
let next_task_cx_ptr = &inner.tasks[next].task_cx as *const TaskContext;
|
|
|
|
|
drop(inner);
|
|
|
|
|
unsafe {
|
|
|
|
|
__switch(
|
|
|
|
|
current_task_cx_ptr2,
|
|
|
|
|
next_task_cx_ptr2,
|
|
|
|
|
current_task_cx_ptr,
|
|
|
|
|
next_task_cx_ptr,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|