diff --git a/src/kernel/scheduler.rs b/src/kernel/scheduler.rs index 7071fbb..07c3506 100644 --- a/src/kernel/scheduler.rs +++ b/src/kernel/scheduler.rs @@ -3,12 +3,12 @@ use std::rc::Rc; use crate::utility::list::List; use crate::kernel::thread::Thread; +use super::system::System; use super::thread_manager::ThreadManager; #[derive(PartialEq)] pub struct Scheduler { - ready_list: List>>, - pub thread_manager: Option>> + ready_list: List>> } impl Scheduler { @@ -18,8 +18,7 @@ impl Scheduler { /// Initilize the list of ready thread pub fn new() -> Self { Self { - ready_list: List::new(), - thread_manager: Option::None + ready_list: List::new() } } @@ -54,21 +53,17 @@ impl Scheduler { /// ## Parameter /// /// **next_thread** thread to dispatch to the CPU - pub fn switch_to(&mut self, next_thread: Rc>) { - if let Some(tm) = &self.thread_manager { - let rc = Rc::clone(&tm); - if let Some(old_thread) = tm.borrow_mut().get_g_current_thread() { - rc.borrow_mut().thread_save_processor_state(Rc::clone(&old_thread)); - // old_thread.save_simulator_state(); + pub fn switch_to(&mut self, system: &mut System, next_thread: Rc>) { + let thread_manager = system.get_thread_manager(); + if let Some(old_thread) = thread_manager.get_g_current_thread() { + thread_manager.thread_save_processor_state(system, Rc::clone(&old_thread)); + // old_thread.save_simulator_state(); - if old_thread != &next_thread { - rc.borrow_mut().thread_restore_processor_state(Rc::clone(&next_thread)); - // next_thread.restore_simulator_state(); - rc.borrow_mut().set_g_current_thread(Option::Some(next_thread)); - } + if old_thread != &next_thread { + thread_manager.thread_restore_processor_state(system, Rc::clone(&next_thread)); + // next_thread.restore_simulator_state(); + thread_manager.set_g_current_thread(Option::Some(next_thread)); } - } else { - panic!("thread manager shouldn't be none"); } } } \ No newline at end of file diff --git a/src/kernel/system.rs b/src/kernel/system.rs index 5144956..e3aaf73 100644 --- a/src/kernel/system.rs +++ b/src/kernel/system.rs @@ -16,10 +16,7 @@ macro_rules! init_system { init_system!(m) }}; ($a:expr) => {{ - let sys = std::rc::Rc::new(std::cell::RefCell::new(crate::System::new($a))); - crate::System::freeze(std::rc::Rc::clone(&sys)); - sys - + $crate::System::new($a) }}; } @@ -36,7 +33,7 @@ macro_rules! init_system { #[derive(PartialEq)] pub struct System { machine: Machine, - thread_manager: Rc> + thread_manager: ThreadManager } impl System { @@ -45,34 +42,26 @@ impl System { pub fn new(machine: Machine) -> System { Self { machine, - thread_manager: Rc::new(RefCell::new(ThreadManager::new())) + thread_manager: ThreadManager::new() } } - /// use thread_manager setter to send it system instance - pub fn freeze(this: Rc>) { - let copy = Rc::clone(&this); - let tm = &this.borrow_mut().thread_manager; - tm.borrow_mut().system = Option::Some(copy); - ThreadManager::freeze(tm); - } - // GETTERS /// Returns the Machine /// /// Useful to access RAM, devices, ... - pub fn get_machine(&self) -> Machine { - self.machine + pub fn get_machine(&self) -> &Machine { + &self.machine } - pub fn get_thread_manager(&self) -> Rc> { - Rc::clone(&self.thread_manager) + pub fn get_thread_manager(&self) -> &ThreadManager { + &self.thread_manager } // Setters - /// Assign a machine to the system + /// Assign a machine to the system pub fn set_machine(&mut self, machine: Machine) { self.machine = machine } diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index 6d0ddeb..5820906 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -36,11 +36,6 @@ impl ThreadManager { } } - pub fn freeze(this: &Rc>) { - let copy = Rc::clone(this); - this.borrow_mut().g_scheduler.thread_manager = Option::Some(copy); - } - /// Start a thread, attaching it to a process pub fn start_thread(&mut self, thread: Rc>, owner: Process, func_pc: i64, argument: i64) -> Result<(), ErrorCode> { let mut thread_m = thread.borrow_mut(); @@ -57,93 +52,71 @@ impl ThreadManager { } /// Wait for another thread to finish its execution - pub fn thread_join(&mut self, id_thread: Rc>) { + pub fn thread_join(&mut self, system: &mut System, id_thread: Rc>) { while self.get_g_alive().contains(&Rc::clone(&id_thread)) { - self.thread_yield(Rc::clone(&id_thread)); + self.thread_yield(system, Rc::clone(&id_thread)); } } /// Relinquish the CPU if any other thread is runnable. /// /// Cannot use yield as a function name -> reserved name in rust - pub fn thread_yield(&mut self, thread: Rc>) { - if let Some(system) = &self.system { - let sys = system.borrow_mut(); - let mut machine = sys.get_machine(); - let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff); + pub fn thread_yield(&mut self, system: &mut System, thread: Rc>) { + let mut machine = system.get_machine(); + let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff); - assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread); - let next_thread = self.g_scheduler.find_next_to_run(); - if let Some(next_thread) = next_thread { - let scheduler = &mut self.g_scheduler; - scheduler.ready_to_run(thread); - scheduler.switch_to(next_thread); - } - machine.interrupt.set_status(old_status); + assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread); + let next_thread = self.g_scheduler.find_next_to_run(); + if let Some(next_thread) = next_thread { + let scheduler = &mut self.g_scheduler; + scheduler.ready_to_run(thread); + scheduler.switch_to(system, next_thread); } + machine.interrupt.set_status(old_status); } /// Put the thread to sleep and relinquish the processor - pub fn thread_sleep(&mut self, thread: Rc>) { - + pub fn thread_sleep(&mut self, system: &mut System, thread: Rc>) { assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread); - if let Some(system) = &self.system { - let sys = system.borrow_mut(); - let machine = sys.get_machine(); - assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff); - - let mut next_thread = self.g_scheduler.find_next_to_run(); - while next_thread.is_none() { - eprintln!("Nobody to run => idle"); - machine.interrupt.idle(); - next_thread = self.g_scheduler.find_next_to_run(); - } - self.g_scheduler.switch_to(Rc::clone(&next_thread.unwrap())); - + let machine = system.get_machine(); + assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff); + let mut next_thread = self.g_scheduler.find_next_to_run(); + while next_thread.is_none() { + eprintln!("Nobody to run => idle"); + machine.interrupt.idle(); + next_thread = self.g_scheduler.find_next_to_run(); } + self.g_scheduler.switch_to(system, Rc::clone(&next_thread.unwrap())); } /// Finish the execution of the thread and prepare its deallocation - pub fn thread_finish(&mut self, thread: Rc>) { - if let Some(system) = &self.system { - let sys = Rc::clone(system); - let sys = sys.borrow_mut(); - let mut machine = sys.get_machine(); - let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); - self.g_thread_to_be_destroyed = Option::Some(Rc::clone(&thread)); - self.g_alive.remove(Rc::clone(&thread)); - // g_objets_addrs->removeObject(self.thread) // a ajouté plus tard - self.thread_sleep(Rc::clone(&thread)); - machine.interrupt.set_status(old_status); + pub fn thread_finish(&mut self, system: &mut System, thread: Rc>) { + let mut machine = system.get_machine(); + let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); + self.g_thread_to_be_destroyed = Option::Some(Rc::clone(&thread)); + self.g_alive.remove(Rc::clone(&thread)); + // g_objets_addrs->removeObject(self.thread) // a ajouté plus tard + self.thread_sleep(system, Rc::clone(&thread)); + machine.interrupt.set_status(old_status); + } + + pub fn thread_save_processor_state(&mut self, system: &mut System, thread: Rc>) { + let mut t: RefMut<_> = thread.borrow_mut(); + for i in 0..NUM_INT_REGS { + t.thread_context.int_registers[i] = system.get_machine().read_int_register(i); + } + for i in 0..NUM_FP_REGS { + t.thread_context.float_registers[i] = system.get_machine().read_fp_register(i); } } - pub fn thread_save_processor_state(&mut self, thread: Rc>) { - if let Some(system) = &self.system { - let mut t: RefMut<_> = thread.borrow_mut(); - let system = system; - for i in 0..NUM_INT_REGS { - t.thread_context.int_registers[i] = system.get_machine().read_int_register(i); - } - for i in 0..NUM_FP_REGS { - t.thread_context.float_registers[i] = system.get_machine().read_fp_register(i); - } - } else { - unreachable!("System is None") - } - } + pub fn thread_restore_processor_state(&self, system: &mut System, thread: Rc>) { - pub fn thread_restore_processor_state(&self, thread: Rc>) { - if let Some(system) = &self.system { - let system = system.borrow_mut(); - let t: Ref<_> = thread.borrow(); - for i in 0..NUM_INT_REGS { - let machine = system.get_machine(); - let mut machine = machine; - machine.write_int_register(i, t.thread_context.int_registers[i]); - } - } else { - unreachable!("System is None") + let t: Ref<_> = thread.borrow(); + for i in 0..NUM_INT_REGS { + let machine = system.get_machine(); + let mut machine = machine; + machine.write_int_register(i, t.thread_context.int_registers[i]); } } diff --git a/src/main.rs b/src/main.rs index e556b8e..b35b860 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,4 @@ use simulator::machine::Machine; fn main() { let machine = Machine::init_machine(); let system = Rc::new(RefCell::new(System::new(machine))); - - System::freeze(system); }