Merge branch 'dev' into main

This commit is contained in:
Yifan Wu 2021-02-16 20:51:03 +08:00
commit 24a31f9d5f
3 changed files with 24 additions and 30 deletions

View file

@ -28,14 +28,13 @@ pub fn suspend_current_and_run_next() {
// There must be an application running. // There must be an application running.
let task = take_current_task().unwrap(); let task = take_current_task().unwrap();
// ---- temporarily hold current PCB lock // ---- hold current PCB lock
let task_cx_ptr2 = task.acquire_inner_lock().get_task_cx_ptr2(); let mut task_inner = task.acquire_inner_lock();
// ---- release current PCB lock let task_cx_ptr2 = task_inner.get_task_cx_ptr2();
// ++++ temporarily hold current PCB lock
// Change status to Ready // Change status to Ready
task.acquire_inner_lock().task_status = TaskStatus::Ready; task_inner.task_status = TaskStatus::Ready;
// ++++ release current PCB lock drop(task_inner);
// ---- release current PCB lock
// push back to ready queue. // push back to ready queue.
add_task(task); add_task(task);
@ -58,6 +57,7 @@ pub fn exit_current_and_run_next(exit_code: i32) {
{ {
let mut initproc_inner = INITPROC.acquire_inner_lock(); let mut initproc_inner = INITPROC.acquire_inner_lock();
for child in inner.children.iter() { for child in inner.children.iter() {
child.acquire_inner_lock().parent = Some(Arc::downgrade(&INITPROC));
initproc_inner.children.push(child.clone()); initproc_inner.children.push(child.clone());
} }
} }

View file

@ -1,13 +1,13 @@
use super::TaskControlBlock; use super::TaskControlBlock;
use alloc::sync::Arc; use alloc::sync::Arc;
use spin::Mutex; use core::cell::RefCell;
use lazy_static::*; use lazy_static::*;
use super::{fetch_task, TaskStatus}; use super::{fetch_task, TaskStatus};
use super::__switch; use super::__switch;
use crate::trap::TrapContext; use crate::trap::TrapContext;
pub struct Processor { pub struct Processor {
inner: Mutex<ProcessorInner>, inner: RefCell<ProcessorInner>,
} }
unsafe impl Sync for Processor {} unsafe impl Sync for Processor {}
@ -20,14 +20,14 @@ struct ProcessorInner {
impl Processor { impl Processor {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
inner: Mutex::new(ProcessorInner { inner: RefCell::new(ProcessorInner {
current: None, current: None,
idle_task_cx_ptr: 0, idle_task_cx_ptr: 0,
}), }),
} }
} }
fn get_idle_task_cx_ptr2(&self) -> *const usize { fn get_idle_task_cx_ptr2(&self) -> *const usize {
let inner = self.inner.lock(); let inner = self.inner.borrow();
&inner.idle_task_cx_ptr as *const usize &inner.idle_task_cx_ptr as *const usize
} }
pub fn run(&self) { pub fn run(&self) {
@ -35,10 +35,12 @@ impl Processor {
if let Some(task) = fetch_task() { if let Some(task) = fetch_task() {
let idle_task_cx_ptr2 = self.get_idle_task_cx_ptr2(); let idle_task_cx_ptr2 = self.get_idle_task_cx_ptr2();
// acquire // acquire
let next_task_cx_ptr2 = task.acquire_inner_lock().get_task_cx_ptr2(); let mut task_inner = task.acquire_inner_lock();
task.acquire_inner_lock().task_status = TaskStatus::Running; let next_task_cx_ptr2 = task_inner.get_task_cx_ptr2();
task_inner.task_status = TaskStatus::Running;
drop(task_inner);
// release // release
self.inner.lock().current = Some(task); self.inner.borrow_mut().current = Some(task);
unsafe { unsafe {
__switch( __switch(
idle_task_cx_ptr2, idle_task_cx_ptr2,
@ -49,10 +51,10 @@ impl Processor {
} }
} }
pub fn take_current(&self) -> Option<Arc<TaskControlBlock>> { pub fn take_current(&self) -> Option<Arc<TaskControlBlock>> {
self.inner.lock().current.take() self.inner.borrow_mut().current.take()
} }
pub fn current(&self) -> Option<Arc<TaskControlBlock>> { pub fn current(&self) -> Option<Arc<TaskControlBlock>> {
self.inner.lock().current.as_ref().map(|task| task.clone()) self.inner.borrow().current.as_ref().map(|task| Arc::clone(task))
} }
} }

View file

@ -67,7 +67,6 @@ impl TaskControlBlock {
.translate(VirtAddr::from(TRAP_CONTEXT).into()) .translate(VirtAddr::from(TRAP_CONTEXT).into())
.unwrap() .unwrap()
.ppn(); .ppn();
let task_status = TaskStatus::Ready;
// alloc a pid and a kernel stack in kernel space // alloc a pid and a kernel stack in kernel space
let pid_handle = pid_alloc(); let pid_handle = pid_alloc();
let kernel_stack = KernelStack::new(&pid_handle); let kernel_stack = KernelStack::new(&pid_handle);
@ -81,7 +80,7 @@ impl TaskControlBlock {
trap_cx_ppn, trap_cx_ppn,
base_size: user_sp, base_size: user_sp,
task_cx_ptr: task_cx_ptr as usize, task_cx_ptr: task_cx_ptr as usize,
task_status, task_status: TaskStatus::Ready,
memory_set, memory_set,
parent: None, parent: None,
children: Vec::new(), children: Vec::new(),
@ -97,9 +96,7 @@ impl TaskControlBlock {
}), }),
}; };
// prepare TrapContext in user space // prepare TrapContext in user space
// ---- acquire child PCB lock
let trap_cx = task_control_block.acquire_inner_lock().get_trap_cx(); let trap_cx = task_control_block.acquire_inner_lock().get_trap_cx();
// ---- release child PCB lock
*trap_cx = TrapContext::app_init_context( *trap_cx = TrapContext::app_init_context(
entry_point, entry_point,
user_sp, user_sp,
@ -118,18 +115,13 @@ impl TaskControlBlock {
.ppn(); .ppn();
// **** hold current PCB lock // **** hold current PCB lock
let mut inner = self.inner.lock(); let mut inner = self.acquire_inner_lock();
// substitute memory_set // substitute memory_set
inner.memory_set = memory_set; inner.memory_set = memory_set;
// update trap_cx ppn // update trap_cx ppn
inner.trap_cx_ppn = trap_cx_ppn; inner.trap_cx_ppn = trap_cx_ppn;
drop(inner);
// **** release current PCB lock manually
// initialize trap_cx // initialize trap_cx
// **** acquire current PCB lock let trap_cx = inner.get_trap_cx();
let trap_cx = self.acquire_inner_lock().get_trap_cx();
// **** release current PCB lock
*trap_cx = TrapContext::app_init_context( *trap_cx = TrapContext::app_init_context(
entry_point, entry_point,
user_sp, user_sp,
@ -137,10 +129,11 @@ impl TaskControlBlock {
self.kernel_stack.get_top(), self.kernel_stack.get_top(),
trap_handler as usize, trap_handler as usize,
); );
// **** release current PCB lock
} }
pub fn fork(self: &Arc<TaskControlBlock>) -> Arc<TaskControlBlock> { pub fn fork(self: &Arc<TaskControlBlock>) -> Arc<TaskControlBlock> {
// ---- hold parent PCB lock // ---- hold parent PCB lock
let mut parent_inner = self.inner.lock(); let mut parent_inner = self.acquire_inner_lock();
// copy user space(include trap context) // copy user space(include trap context)
let memory_set = MemorySet::from_existed_user( let memory_set = MemorySet::from_existed_user(
&parent_inner.memory_set &parent_inner.memory_set
@ -149,7 +142,6 @@ impl TaskControlBlock {
.translate(VirtAddr::from(TRAP_CONTEXT).into()) .translate(VirtAddr::from(TRAP_CONTEXT).into())
.unwrap() .unwrap()
.ppn(); .ppn();
let task_status = TaskStatus::Ready;
// alloc a pid and a kernel stack in kernel space // alloc a pid and a kernel stack in kernel space
let pid_handle = pid_alloc(); let pid_handle = pid_alloc();
let kernel_stack = KernelStack::new(&pid_handle); let kernel_stack = KernelStack::new(&pid_handle);
@ -172,7 +164,7 @@ impl TaskControlBlock {
trap_cx_ppn, trap_cx_ppn,
base_size: parent_inner.base_size, base_size: parent_inner.base_size,
task_cx_ptr: task_cx_ptr as usize, task_cx_ptr: task_cx_ptr as usize,
task_status, task_status: TaskStatus::Ready,
memory_set, memory_set,
parent: Some(Arc::downgrade(self)), parent: Some(Arc::downgrade(self)),
children: Vec::new(), children: Vec::new(),