From 9b65abcfa8c5d7aeac6954b5afa1d9c90fb225d7 Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Tue, 16 Feb 2021 20:50:24 +0800 Subject: [PATCH] Fix lock uses in ch5 --- os/src/task/mod.rs | 14 +++++++------- os/src/task/processor.rs | 8 +++++--- os/src/task/task.rs | 16 ++++------------ 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 31bc435a..e943016c 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -28,14 +28,13 @@ pub fn suspend_current_and_run_next() { // There must be an application running. let task = take_current_task().unwrap(); - // ---- temporarily hold current PCB lock - let task_cx_ptr2 = task.acquire_inner_lock().get_task_cx_ptr2(); - // ---- release current PCB lock - - // ++++ temporarily hold current PCB lock + // ---- hold current PCB lock + let mut task_inner = task.acquire_inner_lock(); + let task_cx_ptr2 = task_inner.get_task_cx_ptr2(); // Change status to Ready - task.acquire_inner_lock().task_status = TaskStatus::Ready; - // ++++ release current PCB lock + task_inner.task_status = TaskStatus::Ready; + drop(task_inner); + // ---- release current PCB lock // push back to ready queue. 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(); for child in inner.children.iter() { + child.acquire_inner_lock().parent = Some(Arc::downgrade(&INITPROC)); initproc_inner.children.push(child.clone()); } } diff --git a/os/src/task/processor.rs b/os/src/task/processor.rs index a1c753f0..e6895c40 100644 --- a/os/src/task/processor.rs +++ b/os/src/task/processor.rs @@ -35,8 +35,10 @@ impl Processor { if let Some(task) = fetch_task() { let idle_task_cx_ptr2 = self.get_idle_task_cx_ptr2(); // acquire - let next_task_cx_ptr2 = task.acquire_inner_lock().get_task_cx_ptr2(); - task.acquire_inner_lock().task_status = TaskStatus::Running; + let mut task_inner = task.acquire_inner_lock(); + let next_task_cx_ptr2 = task_inner.get_task_cx_ptr2(); + task_inner.task_status = TaskStatus::Running; + drop(task_inner); // release self.inner.borrow_mut().current = Some(task); unsafe { @@ -52,7 +54,7 @@ impl Processor { self.inner.borrow_mut().current.take() } pub fn current(&self) -> Option> { - self.inner.borrow().current.as_ref().map(|task| task.clone()) + self.inner.borrow().current.as_ref().map(|task| Arc::clone(task)) } } diff --git a/os/src/task/task.rs b/os/src/task/task.rs index e58c8ae8..1c733da1 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -67,7 +67,6 @@ impl TaskControlBlock { .translate(VirtAddr::from(TRAP_CONTEXT).into()) .unwrap() .ppn(); - let task_status = TaskStatus::Ready; // alloc a pid and a kernel stack in kernel space let pid_handle = pid_alloc(); let kernel_stack = KernelStack::new(&pid_handle); @@ -81,7 +80,7 @@ impl TaskControlBlock { trap_cx_ppn, base_size: user_sp, task_cx_ptr: task_cx_ptr as usize, - task_status, + task_status: TaskStatus::Ready, memory_set, parent: None, children: Vec::new(), @@ -97,9 +96,7 @@ impl TaskControlBlock { }), }; // prepare TrapContext in user space - // ---- acquire child PCB lock let trap_cx = task_control_block.acquire_inner_lock().get_trap_cx(); - // ---- release child PCB lock *trap_cx = TrapContext::app_init_context( entry_point, user_sp, @@ -123,13 +120,8 @@ impl TaskControlBlock { inner.memory_set = memory_set; // update trap_cx ppn inner.trap_cx_ppn = trap_cx_ppn; - drop(inner); - // **** release current PCB lock manually - // initialize trap_cx - // **** acquire current PCB lock - let trap_cx = self.acquire_inner_lock().get_trap_cx(); - // **** release current PCB lock + let trap_cx = inner.get_trap_cx(); *trap_cx = TrapContext::app_init_context( entry_point, user_sp, @@ -137,6 +129,7 @@ impl TaskControlBlock { self.kernel_stack.get_top(), trap_handler as usize, ); + // **** release current PCB lock } pub fn fork(self: &Arc) -> Arc { // ---- hold parent PCB lock @@ -149,7 +142,6 @@ impl TaskControlBlock { .translate(VirtAddr::from(TRAP_CONTEXT).into()) .unwrap() .ppn(); - let task_status = TaskStatus::Ready; // alloc a pid and a kernel stack in kernel space let pid_handle = pid_alloc(); let kernel_stack = KernelStack::new(&pid_handle); @@ -172,7 +164,7 @@ impl TaskControlBlock { trap_cx_ppn, base_size: parent_inner.base_size, task_cx_ptr: task_cx_ptr as usize, - task_status, + task_status: TaskStatus::Ready, memory_set, parent: Some(Arc::downgrade(self)), children: Vec::new(),