diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index 6b74e57..b8f19d3 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -257,29 +257,24 @@ impl ThreadManager { /// - **id** id of the lock, stored in [`ObjAddr`], id given by user program thought exceptions /// - **machine** the machine where the threads are executed pub fn lock_acquire(&mut self, id: i32, machine: &mut Machine) -> Result { - match self.get_g_current_thread() { - Some(thread) => { - let rc_thread = Rc::clone(thread); - let lock = self.get_obj_addrs().search_lock(id); - match lock { - Some(lock) => { - let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); - if lock.free { - lock.free = false; - lock.owner = Some(Rc::clone(&rc_thread)) - } else { - let thread = Rc::clone(&rc_thread); - lock.waiting_queue.push(Rc::clone(&thread)); - self.thread_sleep(machine, Rc::clone(&thread)); - } - machine.interrupt.set_status(old_status); - Ok(MachineOk::Ok) - }, - None => Err("Cannot find lock")? - } - }, - None => unreachable!("Current thread should not be None") + let current_thread = match self.get_g_current_thread() { + Some(thread) => Rc::clone(thread), + None => Err("lock_acquire error: current_thread should not be None.")? + }; + let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); + if let Some(lock) = self.get_obj_addrs().search_lock(id) { + if lock.free { + lock.free = false; + lock.owner = Some(current_thread) + } else { + lock.waiting_queue.push(current_thread.clone()); + self.thread_sleep(machine, current_thread); + } + } else { + Err("lock_acquire error: cannot find Lock.")? } + machine.interrupt.set_status(old_status); + Ok(MachineOk::Ok) } /// Wake up a waiter if necessary, or release it if no thread is waiting.