♻️ Clean-up of some nasty nesting in sem_v and sem_p
This commit is contained in:
parent
5734e02b30
commit
8b13cc6ef6
@ -69,26 +69,22 @@ 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);
|
|
||||||
self.thread_save_processor_state(machine, old1);
|
|
||||||
// old_thread.save_simulator_state();
|
// old_thread.save_simulator_state();
|
||||||
if old2 != next_thread {
|
if old_thread != next_thread {
|
||||||
self.debug(format!("switching from \"{}\" to \"{}\"", old2.borrow().get_name(), next_thread.borrow().get_name()));
|
self.debug(format!("switching from \"{}\" to \"{}\"", old_thread.borrow().get_name(), next_thread.borrow().get_name()));
|
||||||
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));
|
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 {
|
||||||
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();
|
||||||
self.set_g_current_thread(Some(next_thread));
|
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() {
|
||||||
drop(th);
|
drop(th);
|
||||||
@ -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() {
|
|
||||||
Some(thread) => {
|
|
||||||
let rc1_thread = Rc::clone(thread);
|
|
||||||
let rc2_thread = Rc::clone(thread);
|
|
||||||
let sema = self.get_obj_addrs().search_semaphore(id_sema as i32);
|
|
||||||
if let Some(sema) = sema {
|
|
||||||
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
||||||
|
let thread = match self.get_g_current_thread() {
|
||||||
|
Some(thread) => Rc::clone(thread),
|
||||||
|
None => Err("sem_p error: current thread should not be None")?
|
||||||
|
};
|
||||||
|
let sema = match self.get_obj_addrs().search_semaphore(id_sema) {
|
||||||
|
Some(sema) => sema,
|
||||||
|
None => Err("sem_p error: cannot find semaphore")?
|
||||||
|
};
|
||||||
sema.counter -= 1;
|
sema.counter -= 1;
|
||||||
if sema.counter < 0 {
|
if sema.counter < 0 {
|
||||||
sema.waiting_queue.push(rc1_thread);
|
sema.waiting_queue.push(thread.clone());
|
||||||
self.thread_sleep(machine, rc2_thread);
|
self.thread_sleep(machine, thread);
|
||||||
}
|
}
|
||||||
machine.interrupt.set_status(old_status);
|
machine.interrupt.set_status(old_status);
|
||||||
Ok(MachineOk::Ok)
|
Ok(MachineOk::Ok)
|
||||||
} else {
|
|
||||||
Err("Cannot find semaphore")?
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => unreachable!("Current thread should not be None")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Increment semaphore value, waking up a waiting thread if any.
|
/// Increment semaphore value, waking up a waiting thread if any.
|
||||||
@ -225,9 +216,10 @@ 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);
|
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
||||||
sema.counter += 1;
|
sema.counter += 1;
|
||||||
match sema.waiting_queue.pop() {
|
match sema.waiting_queue.pop() {
|
||||||
@ -236,12 +228,6 @@ impl ThreadManager {
|
|||||||
}
|
}
|
||||||
machine.interrupt.set_status(old_status);
|
machine.interrupt.set_status(old_status);
|
||||||
Ok(MachineOk::Ok)
|
Ok(MachineOk::Ok)
|
||||||
},
|
|
||||||
None => {
|
|
||||||
Err("Cannot find semaphore")?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user