diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index d24988a..6b74e57 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -1,4 +1,4 @@ -use std::{rc::Rc, cell::{RefCell, Ref}}; +use std::{rc::Rc, cell::{RefCell, Ref}, fmt::format}; use crate::{utility::{list::List, objaddr::ObjAddr}, simulator::{machine::{NUM_INT_REGS, NUM_FP_REGS, Machine}, interrupt::InterruptStatus, error::{MachineOk, MachineError}}}; @@ -284,48 +284,30 @@ impl ThreadManager { /// Wake up a waiter if necessary, or release it if no thread is waiting. pub fn lock_release(&mut self, id: i32, machine: &mut Machine) -> Result { - let current_thread = self.get_g_current_thread(); - match current_thread { - Some(thread) => { - let current_thread = Rc::clone(&thread); - - let mut lock_option = self.get_obj_addrs().search_lock(id).cloned(); - match lock_option { - Some(mut lock) => { - let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); - - match &lock.owner { - Some(lock_owner) => { - if Rc::ptr_eq(¤t_thread, lock_owner) { - match lock.waiting_queue.pop() { - Some(thread) => { - lock.owner = Some(thread); - match &lock.owner { - Some(x) => { - self.ready_to_run(Rc::clone(x)); - lock.free = true; - }, - None => () - } - }, - None => { - lock.free = true; - lock.owner = None; - } - } - } - }, - None => () - } - machine.interrupt.set_status(old_status); - Ok(MachineOk::Ok) - }, - None => Err("Cannot find lock")? + let current_thread = match self.get_g_current_thread() { + Some(thread) => Rc::clone(&thread), + None => Err(String::from("lock_release error: current_thread should not be None."))? + }; + let mut lock = match self.get_obj_addrs().search_lock(id).cloned() { + Some(lock) => lock, + None => Err(String::from("lock_release error: cannot find lock."))? + }; + let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); + if let Some(lock_owner) = &lock.owner { + if Rc::ptr_eq(¤t_thread, lock_owner) { + if let Some(thread) = lock.waiting_queue.pop() { + let clone = Rc::clone(&thread); + lock.owner = Some(thread); + self.ready_to_run(clone); + lock.free = true; + } else { + lock.free = true; + lock.owner = None; } - }, - None => unreachable!("Current thread should not be None") - } - + } + }; + machine.interrupt.set_status(old_status); + Ok(MachineOk::Ok) } /// Currently running thread