From 7de7f2e0075ed99694287bf1faa0d0c69ecdafbe Mon Sep 17 00:00:00 2001 From: Quentin Legot Date: Mon, 13 Mar 2023 21:47:06 +0100 Subject: [PATCH] Fix scheduler switch_to by making a lot of change(use smart pointers in place of lifetime reference) --- src/kernel/scheduler.rs | 32 +++++++++++++---------- src/kernel/synch.rs | 18 ++++++------- src/kernel/system.rs | 19 ++++++++------ src/kernel/thread_manager.rs | 50 +++++++++++++++++++----------------- src/main.rs | 7 +++-- 5 files changed, 71 insertions(+), 55 deletions(-) diff --git a/src/kernel/scheduler.rs b/src/kernel/scheduler.rs index f98e7d6..7071fbb 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>> + ready_list: List>>, + pub thread_manager: Option>> } impl Scheduler { @@ -18,7 +18,8 @@ impl Scheduler { /// Initilize the list of ready thread pub fn new() -> Self { Self { - ready_list: List::new() + ready_list: List::new(), + thread_manager: Option::None } } @@ -53,16 +54,21 @@ impl Scheduler { /// ## Parameter /// /// **next_thread** thread to dispatch to the CPU - pub fn switch_to(&self, system: &System, next_thread: Rc>) { - /* if let Some(old_thread) = system.get_g_current_thread() { - old_thread.save_processor_state(); - old_thread.save_simulator_state(); + 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(); - if old_thread != &next_thread { - next_thread.restore_processor_state(); - next_thread.restore_simulator_state(); - system.set_g_current_thread(Option::Some(next_thread)); + 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)); + } } - } */ + } else { + panic!("thread manager shouldn't be none"); + } } } \ No newline at end of file diff --git a/src/kernel/synch.rs b/src/kernel/synch.rs index 77fc56c..85df6ec 100644 --- a/src/kernel/synch.rs +++ b/src/kernel/synch.rs @@ -9,15 +9,15 @@ use std::rc::Rc; use super::scheduler::Scheduler; use super::thread_manager::ThreadManager; -pub struct Semaphore<'t> { +pub struct Semaphore { counter:i32, waiting_queue:List>>, - thread_manager: Rc>> // On s'assure que le tm vit plus longtemps que les semaphore avec le lifetime + thread_manager: Rc> // On s'assure que le tm vit plus longtemps que les semaphore avec le lifetime } -impl<'t> Semaphore<'_> { +impl Semaphore { pub fn p(&mut self, current_thread: Rc>, machine: &mut Machine){ let old_status = machine.interrupt.set_status(InterruptOff); @@ -39,16 +39,16 @@ impl<'t> Semaphore<'_> { } } -pub struct Lock<'t>{ +pub struct Lock{ owner: Rc>, waiting_queue:List>>, - thread_manager: Rc>>, + thread_manager: Rc>, free: bool } -impl<'t> Lock<'_> { +impl Lock { pub fn acquire(&mut self, machine: &mut Machine, current_thread: Rc>) { let old_status = machine.interrupt.set_status(InterruptOff); @@ -83,14 +83,14 @@ impl<'t> Lock<'_> { } } -pub struct Condition<'t>{ +pub struct Condition{ waiting_queue:List>>, - thread_manager: Rc>>, + thread_manager: Rc>, } -impl<'t> Condition<'_> { +impl Condition { pub fn wait(&mut self, machine: &mut Machine, current_thread: Rc>) { let old_status = machine.interrupt.set_status(InterruptOff); diff --git a/src/kernel/system.rs b/src/kernel/system.rs index c12d222..b3cb768 100644 --- a/src/kernel/system.rs +++ b/src/kernel/system.rs @@ -1,4 +1,4 @@ -use std::cell::RefCell; +use std::{cell::RefCell, rc::Rc}; use crate::simulator::machine::Machine; @@ -15,24 +15,27 @@ use super::thread_manager::ThreadManager; /// - The thread to be destroyed next /// - The scheduler which acts upon these threads #[derive(PartialEq)] -pub struct System<'a> { +pub struct System { g_machine: RefCell, - thread_manager: ThreadManager<'a> + thread_manager: Rc> } -impl<'a> System<'a> { +impl System { /// System constructor - pub fn new(machine: Machine) -> System<'a> { + pub fn new(machine: Machine) -> System { Self { g_machine: RefCell::new(machine), - thread_manager: ThreadManager::new() + thread_manager: Rc::new(RefCell::new(ThreadManager::new())) } } /// use thread_manager setter to send it system instance - pub fn freeze(&'a mut self) { - self.thread_manager.system.set(Option::Some(self)); + 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 diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index 1788a0b..b4d5632 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -1,4 +1,4 @@ -use std::{rc::Rc, cell::{Cell, RefCell, RefMut, Ref}}; +use std::{rc::Rc, cell::{RefCell, RefMut, Ref}}; use crate::{utility::list::List, simulator::{machine::{NUM_INT_REGS, NUM_FP_REGS}, interrupt::InterruptStatus}}; @@ -7,15 +7,15 @@ use super::{scheduler::Scheduler, thread::Thread, system::System, mgerror::Error pub const SIMULATORSTACKSIZE: usize = 32 * 1024; #[derive(PartialEq)] -pub struct ThreadManager<'a> { +pub struct ThreadManager { pub g_current_thread: Option>>, pub g_thread_to_be_destroyed: Option>>, pub g_alive: List>>, pub g_scheduler: Scheduler, - pub system: Cell>> + pub system: Option>> } -impl<'a> ThreadManager<'a> { +impl ThreadManager { pub fn new() -> Self { Self { @@ -23,10 +23,15 @@ impl<'a> ThreadManager<'a> { g_thread_to_be_destroyed: Option::None, g_alive: List::new(), g_scheduler: Scheduler::new(), - system: Cell::new(None) + system: Option::None } } + 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(); @@ -38,7 +43,7 @@ impl<'a> ThreadManager<'a> { thread_m.init_simulator_context(base_stack_addr); thread_m.process.as_mut().unwrap().num_thread += 1; self.get_g_alive().push(Rc::clone(&thread)); - self.g_scheduler().ready_to_run(Rc::clone(&thread)); + self.g_scheduler.ready_to_run(Rc::clone(&thread)); Result::Ok(()) } @@ -53,16 +58,17 @@ impl<'a> ThreadManager<'a> { /// /// 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.get() { - let mut machine = system.get_g_machine().borrow_mut(); + if let Some(system) = &self.system { + let sys = system.borrow_mut(); + let mut machine = sys.get_g_machine().borrow_mut(); 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(); + let next_thread = self.g_scheduler.find_next_to_run(); if let Some(next_thread) = next_thread { - let scheduler = self.g_scheduler(); + let scheduler = &mut self.g_scheduler; scheduler.ready_to_run(thread); - scheduler.switch_to(system, next_thread); + scheduler.switch_to(next_thread); } machine.interrupt.set_status(old_status); } @@ -72,16 +78,17 @@ impl<'a> ThreadManager<'a> { pub fn thread_sleep(&mut self, thread: Rc>) { assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread); - if let Some(system) = self.system.get() { - let mut machine = system.get_g_machine().borrow_mut(); + if let Some(system) = &self.system { + let sys = system.borrow_mut(); + let machine = sys.get_g_machine().borrow_mut(); assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff); - let mut next_thread = self.g_scheduler().find_next_to_run(); + let mut next_thread = self.g_scheduler.find_next_to_run(); while next_thread.is_none() { machine.interrupt.idle(); - next_thread = self.g_scheduler().find_next_to_run(); + next_thread = self.g_scheduler.find_next_to_run(); } - self.g_scheduler().switch_to(system, Rc::clone(&next_thread.unwrap())); + self.g_scheduler.switch_to(Rc::clone(&next_thread.unwrap())); } } @@ -92,8 +99,9 @@ impl<'a> ThreadManager<'a> { } pub fn thread_save_processor_state(&mut self, thread: Rc>) { - if let Some(system) = self.system.get() { + if let Some(system) = &self.system { let mut t: RefMut<_> = thread.borrow_mut(); + let system = system.borrow_mut(); for i in 0..NUM_INT_REGS { t.thread_context.int_registers[i] = system.get_g_machine().borrow().read_int_register(i); } @@ -106,7 +114,8 @@ impl<'a> ThreadManager<'a> { } pub fn thread_restore_processor_state(&self, thread: Rc>) { - if let Some(system) = self.system.get() { + 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_g_machine(); @@ -135,11 +144,6 @@ impl<'a> ThreadManager<'a> { &mut self.g_alive } - /// Current scheduler - pub fn g_scheduler(&mut self) -> &mut Scheduler { - &mut self.g_scheduler - } - /// Set currently running thread pub fn set_g_current_thread(&mut self, thread: Option>>) { self.g_current_thread = thread diff --git a/src/main.rs b/src/main.rs index 2e01f7d..e556b8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,11 +13,14 @@ mod kernel; /// module containing useful tools which can be use in most part of the OS to ease the development of the OS pub mod utility; +use std::{rc::Rc, cell::RefCell}; + use kernel::system::System; use simulator::machine::Machine; fn main() { let machine = Machine::init_machine(); - let mut system = System::new(machine); - system.freeze(); + let system = Rc::new(RefCell::new(System::new(machine))); + + System::freeze(system); }