提交 946b37a2 编写于 作者: Y Yifan Wu

Fix lock uses in ch5

上级 a15a76ed
......@@ -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());
}
}
......
......@@ -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<Arc<TaskControlBlock>> {
self.inner.borrow().current.as_ref().map(|task| task.clone())
self.inner.borrow().current.as_ref().map(|task| Arc::clone(task))
}
}
......
......@@ -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<TaskControlBlock>) -> Arc<TaskControlBlock> {
// ---- 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(),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册