♻️ Clean-up of some nasty nesting in sem_v and sem_p

This commit is contained in:
François Autin 2023-04-19 23:24:51 +02:00
parent 5734e02b30
commit 8b13cc6ef6
No known key found for this signature in database
GPG Key ID: 343F5D382E1DD77C

View File

@ -69,25 +69,21 @@ impl ThreadManager {
/// ///
/// **next_thread** thread to dispatch to the CPU /// **next_thread** thread to dispatch to the CPU
pub fn switch_to(&mut self, machine: &mut Machine, next_thread: Rc<RefCell<Thread>>) { pub fn switch_to(&mut self, machine: &mut Machine, next_thread: Rc<RefCell<Thread>>) {
match self.get_g_current_thread() { if let Some(old_thread) = self.get_g_current_thread() {
Some(old) => { let old_thread = old_thread.clone();
let old1 = Rc::clone(old); self.thread_save_processor_state(machine, old_thread.clone());
let old2 = Rc::clone(old); // old_thread.save_simulator_state();
self.thread_save_processor_state(machine, old1); if old_thread != next_thread {
// old_thread.save_simulator_state(); self.debug(format!("switching from \"{}\" to \"{}\"", old_thread.borrow().get_name(), next_thread.borrow().get_name()));
if old2 != next_thread {
self.debug(format!("switching from \"{}\" to \"{}\"", old2.borrow().get_name(), next_thread.borrow().get_name()));
self.thread_restore_processor_state(machine, Rc::clone(&next_thread));
// next_thread.restore_simulator_state();
debug_assert!(!self.ready_list.contains(&next_thread));
self.set_g_current_thread(Some(next_thread));
}
},
None => {
self.thread_restore_processor_state(machine, Rc::clone(&next_thread)); self.thread_restore_processor_state(machine, Rc::clone(&next_thread));
// next_thread.restore_simulator_state(); // next_thread.restore_simulator_state();
debug_assert!(!self.ready_list.contains(&next_thread));
self.set_g_current_thread(Some(next_thread)); self.set_g_current_thread(Some(next_thread));
} }
} else {
self.thread_restore_processor_state(machine, Rc::clone(&next_thread));
// next_thread.restore_simulator_state();
self.set_g_current_thread(Some(next_thread));
} }
if let Some(th) = self.get_g_thread_to_be_destroyed() { if let Some(th) = self.get_g_thread_to_be_destroyed() {
@ -123,7 +119,6 @@ impl ThreadManager {
pub fn thread_yield(&mut self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) { pub fn thread_yield(&mut self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) {
let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff); let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff);
self.debug(format!("Yeilding thread: {}", thread.borrow().get_name())); self.debug(format!("Yeilding thread: {}", thread.borrow().get_name()));
debug_assert_eq!(&Option::Some(Rc::clone(&thread)), self.get_g_current_thread()); debug_assert_eq!(&Option::Some(Rc::clone(&thread)), self.get_g_current_thread());
let next_thread = self.find_next_to_run(); let next_thread = self.find_next_to_run();
@ -192,26 +187,22 @@ impl ThreadManager {
/// - *id_sema* id of the semaphore, stored in [`ObjAddr`], id given by user program thought exceptions /// - *id_sema* id of the semaphore, stored in [`ObjAddr`], id given by user program thought exceptions
/// - *machine* Current state of the machine /// - *machine* Current state of the machine
pub fn sem_p(&mut self, id_sema: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> { pub fn sem_p(&mut self, id_sema: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> {
match self.get_g_current_thread() { let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
Some(thread) => { let thread = match self.get_g_current_thread() {
let rc1_thread = Rc::clone(thread); Some(thread) => Rc::clone(thread),
let rc2_thread = Rc::clone(thread); None => Err("sem_p error: current thread should not be None")?
let sema = self.get_obj_addrs().search_semaphore(id_sema as i32); };
if let Some(sema) = sema { let sema = match self.get_obj_addrs().search_semaphore(id_sema) {
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); Some(sema) => sema,
sema.counter -= 1; None => Err("sem_p error: cannot find semaphore")?
if sema.counter < 0 { };
sema.waiting_queue.push(rc1_thread); sema.counter -= 1;
self.thread_sleep(machine, rc2_thread); if sema.counter < 0 {
} sema.waiting_queue.push(thread.clone());
machine.interrupt.set_status(old_status); self.thread_sleep(machine, thread);
Ok(MachineOk::Ok)
} else {
Err("Cannot find semaphore")?
}
},
None => unreachable!("Current thread should not be None")
} }
machine.interrupt.set_status(old_status);
Ok(MachineOk::Ok)
} }
/// Increment semaphore value, waking up a waiting thread if any. /// Increment semaphore value, waking up a waiting thread if any.
@ -225,23 +216,18 @@ impl ThreadManager {
/// - *id_sema* id of the semaphore, stored in [`ObjAddr`], id given by user program thought exceptions /// - *id_sema* id of the semaphore, stored in [`ObjAddr`], id given by user program thought exceptions
/// - **machine** the machine where the threads are executed /// - **machine** the machine where the threads are executed
pub fn sem_v(&mut self, id_sema: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> { pub fn sem_v(&mut self, id_sema: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> {
let sema = self.get_obj_addrs().search_semaphore(id_sema as i32); let sema = match self.get_obj_addrs().search_semaphore(id_sema) {
match sema { Some(sema) => sema,
Some(sema) => { None => Err("sem_v error: cannot find semaphore")?
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); };
sema.counter += 1; let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
match sema.waiting_queue.pop() { sema.counter += 1;
Some(thread) => self.ready_to_run(thread), match sema.waiting_queue.pop() {
None => () Some(thread) => self.ready_to_run(thread),
} None => ()
machine.interrupt.set_status(old_status);
Ok(MachineOk::Ok)
},
None => {
Err("Cannot find semaphore")?
}
} }
machine.interrupt.set_status(old_status);
Ok(MachineOk::Ok)
} }