Moved to reference passing system

This commit is contained in:
François Autin 2023-03-15 15:20:20 +01:00
parent abb97d17d5
commit 1906ec836c
No known key found for this signature in database
GPG Key ID: 343F5D382E1DD77C
4 changed files with 64 additions and 109 deletions

View File

@ -3,12 +3,12 @@ use std::rc::Rc;
use crate::utility::list::List; use crate::utility::list::List;
use crate::kernel::thread::Thread; use crate::kernel::thread::Thread;
use super::system::System;
use super::thread_manager::ThreadManager; use super::thread_manager::ThreadManager;
#[derive(PartialEq)] #[derive(PartialEq)]
pub struct Scheduler { pub struct Scheduler {
ready_list: List<Rc<RefCell<Thread>>>, ready_list: List<Rc<RefCell<Thread>>>
pub thread_manager: Option<Rc<RefCell<ThreadManager>>>
} }
impl Scheduler { impl Scheduler {
@ -18,8 +18,7 @@ impl Scheduler {
/// Initilize the list of ready thread /// Initilize the list of ready thread
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
ready_list: List::new(), ready_list: List::new()
thread_manager: Option::None
} }
} }
@ -54,21 +53,17 @@ impl Scheduler {
/// ## Parameter /// ## Parameter
/// ///
/// **next_thread** thread to dispatch to the CPU /// **next_thread** thread to dispatch to the CPU
pub fn switch_to(&mut self, next_thread: Rc<RefCell<Thread>>) { pub fn switch_to(&mut self, system: &mut System, next_thread: Rc<RefCell<Thread>>) {
if let Some(tm) = &self.thread_manager { let thread_manager = system.get_thread_manager();
let rc = Rc::clone(&tm); if let Some(old_thread) = thread_manager.get_g_current_thread() {
if let Some(old_thread) = tm.borrow_mut().get_g_current_thread() { thread_manager.thread_save_processor_state(system, Rc::clone(&old_thread));
rc.borrow_mut().thread_save_processor_state(Rc::clone(&old_thread)); // old_thread.save_simulator_state();
// old_thread.save_simulator_state();
if old_thread != &next_thread { if old_thread != &next_thread {
rc.borrow_mut().thread_restore_processor_state(Rc::clone(&next_thread)); thread_manager.thread_restore_processor_state(system, Rc::clone(&next_thread));
// next_thread.restore_simulator_state(); // next_thread.restore_simulator_state();
rc.borrow_mut().set_g_current_thread(Option::Some(next_thread)); thread_manager.set_g_current_thread(Option::Some(next_thread));
}
} }
} else {
panic!("thread manager shouldn't be none");
} }
} }
} }

View File

@ -16,10 +16,7 @@ macro_rules! init_system {
init_system!(m) init_system!(m)
}}; }};
($a:expr) => {{ ($a:expr) => {{
let sys = std::rc::Rc::new(std::cell::RefCell::new(crate::System::new($a))); $crate::System::new($a)
crate::System::freeze(std::rc::Rc::clone(&sys));
sys
}}; }};
} }
@ -36,7 +33,7 @@ macro_rules! init_system {
#[derive(PartialEq)] #[derive(PartialEq)]
pub struct System { pub struct System {
machine: Machine, machine: Machine,
thread_manager: Rc<RefCell<ThreadManager>> thread_manager: ThreadManager
} }
impl System { impl System {
@ -45,34 +42,26 @@ impl System {
pub fn new(machine: Machine) -> System { pub fn new(machine: Machine) -> System {
Self { Self {
machine, 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<RefCell<System>>) {
let copy = Rc::clone(&this);
let tm = &this.borrow_mut().thread_manager;
tm.borrow_mut().system = Option::Some(copy);
ThreadManager::freeze(tm);
}
// GETTERS // GETTERS
/// Returns the Machine /// Returns the Machine
/// ///
/// Useful to access RAM, devices, ... /// Useful to access RAM, devices, ...
pub fn get_machine(&self) -> Machine { pub fn get_machine(&self) -> &Machine {
self.machine &self.machine
} }
pub fn get_thread_manager(&self) -> Rc<RefCell<ThreadManager>> { pub fn get_thread_manager(&self) -> &ThreadManager {
Rc::clone(&self.thread_manager) &self.thread_manager
} }
// Setters // Setters
/// Assign a machine to the system /// Assign a machine to the system
pub fn set_machine(&mut self, machine: Machine) { pub fn set_machine(&mut self, machine: Machine) {
self.machine = machine self.machine = machine
} }

View File

@ -36,11 +36,6 @@ impl ThreadManager {
} }
} }
pub fn freeze(this: &Rc<RefCell<ThreadManager>>) {
let copy = Rc::clone(this);
this.borrow_mut().g_scheduler.thread_manager = Option::Some(copy);
}
/// Start a thread, attaching it to a process /// Start a thread, attaching it to a process
pub fn start_thread(&mut self, thread: Rc<RefCell<Thread>>, owner: Process, func_pc: i64, argument: i64) -> Result<(), ErrorCode> { pub fn start_thread(&mut self, thread: Rc<RefCell<Thread>>, owner: Process, func_pc: i64, argument: i64) -> Result<(), ErrorCode> {
let mut thread_m = thread.borrow_mut(); let mut thread_m = thread.borrow_mut();
@ -57,93 +52,71 @@ impl ThreadManager {
} }
/// Wait for another thread to finish its execution /// Wait for another thread to finish its execution
pub fn thread_join(&mut self, id_thread: Rc<RefCell<Thread>>) { pub fn thread_join(&mut self, system: &mut System, id_thread: Rc<RefCell<Thread>>) {
while self.get_g_alive().contains(&Rc::clone(&id_thread)) { 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. /// Relinquish the CPU if any other thread is runnable.
/// ///
/// Cannot use yield as a function name -> reserved name in rust /// Cannot use yield as a function name -> reserved name in rust
pub fn thread_yield(&mut self, thread: Rc<RefCell<Thread>>) { pub fn thread_yield(&mut self, system: &mut System, thread: Rc<RefCell<Thread>>) {
if let Some(system) = &self.system { let mut machine = system.get_machine();
let sys = system.borrow_mut(); let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff);
let mut machine = sys.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); 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 { if let Some(next_thread) = next_thread {
let scheduler = &mut self.g_scheduler; let scheduler = &mut self.g_scheduler;
scheduler.ready_to_run(thread); scheduler.ready_to_run(thread);
scheduler.switch_to(next_thread); scheduler.switch_to(system, next_thread);
}
machine.interrupt.set_status(old_status);
} }
machine.interrupt.set_status(old_status);
} }
/// Put the thread to sleep and relinquish the processor /// Put the thread to sleep and relinquish the processor
pub fn thread_sleep(&mut self, thread: Rc<RefCell<Thread>>) { pub fn thread_sleep(&mut self, system: &mut System, thread: Rc<RefCell<Thread>>) {
assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread); assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread);
if let Some(system) = &self.system { let machine = system.get_machine();
let sys = system.borrow_mut(); assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff);
let machine = sys.get_machine(); let mut next_thread = self.g_scheduler.find_next_to_run();
assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff); while next_thread.is_none() {
eprintln!("Nobody to run => idle");
let mut next_thread = self.g_scheduler.find_next_to_run(); machine.interrupt.idle();
while next_thread.is_none() { next_thread = self.g_scheduler.find_next_to_run();
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()));
} }
self.g_scheduler.switch_to(system, Rc::clone(&next_thread.unwrap()));
} }
/// Finish the execution of the thread and prepare its deallocation /// Finish the execution of the thread and prepare its deallocation
pub fn thread_finish(&mut self, thread: Rc<RefCell<Thread>>) { pub fn thread_finish(&mut self, system: &mut System, thread: Rc<RefCell<Thread>>) {
if let Some(system) = &self.system { let mut machine = system.get_machine();
let sys = Rc::clone(system); let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
let sys = sys.borrow_mut(); self.g_thread_to_be_destroyed = Option::Some(Rc::clone(&thread));
let mut machine = sys.get_machine(); self.g_alive.remove(Rc::clone(&thread));
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); // g_objets_addrs->removeObject(self.thread) // a ajouté plus tard
self.g_thread_to_be_destroyed = Option::Some(Rc::clone(&thread)); self.thread_sleep(system, Rc::clone(&thread));
self.g_alive.remove(Rc::clone(&thread)); machine.interrupt.set_status(old_status);
// 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_save_processor_state(&mut self, system: &mut System, thread: Rc<RefCell<Thread>>) {
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<RefCell<Thread>>) { pub fn thread_restore_processor_state(&self, system: &mut System, thread: Rc<RefCell<Thread>>) {
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, thread: Rc<RefCell<Thread>>) { let t: Ref<_> = thread.borrow();
if let Some(system) = &self.system { for i in 0..NUM_INT_REGS {
let system = system.borrow_mut(); let machine = system.get_machine();
let t: Ref<_> = thread.borrow(); let mut machine = machine;
for i in 0..NUM_INT_REGS { machine.write_int_register(i, t.thread_context.int_registers[i]);
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")
} }
} }

View File

@ -21,6 +21,4 @@ use simulator::machine::Machine;
fn main() { fn main() {
let machine = Machine::init_machine(); let machine = Machine::init_machine();
let system = Rc::new(RefCell::new(System::new(machine))); let system = Rc::new(RefCell::new(System::new(machine)));
System::freeze(system);
} }