♻️ Refactored lock_release

This commit is contained in:
François Autin 2023-04-19 21:30:28 +02:00
parent efe00ffa26
commit f55189f1fe

View File

@ -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}}}; 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. /// 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<MachineOk, MachineError> { pub fn lock_release(&mut self, id: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> {
let current_thread = self.get_g_current_thread(); let current_thread = match self.get_g_current_thread() {
match current_thread { Some(thread) => Rc::clone(&thread),
Some(thread) => { None => Err(String::from("lock_release error: current_thread should not be None."))?
let current_thread = Rc::clone(&thread); };
let mut lock = match self.get_obj_addrs().search_lock(id).cloned() {
let mut lock_option = self.get_obj_addrs().search_lock(id).cloned(); Some(lock) => lock,
match lock_option { None => Err(String::from("lock_release error: cannot find lock."))?
Some(mut lock) => { };
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
if let Some(lock_owner) = &lock.owner {
match &lock.owner { if Rc::ptr_eq(&current_thread, lock_owner) {
Some(lock_owner) => { if let Some(thread) = lock.waiting_queue.pop() {
if Rc::ptr_eq(&current_thread, lock_owner) { let clone = Rc::clone(&thread);
match lock.waiting_queue.pop() { lock.owner = Some(thread);
Some(thread) => { self.ready_to_run(clone);
lock.owner = Some(thread); lock.free = true;
match &lock.owner { } else {
Some(x) => { lock.free = true;
self.ready_to_run(Rc::clone(x)); lock.owner = None;
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")?
} }
}, }
None => unreachable!("Current thread should not be None") };
} machine.interrupt.set_status(old_status);
Ok(MachineOk::Ok)
} }
/// Currently running thread /// Currently running thread