update synch.rs

This commit is contained in:
Samy Solhi 2023-03-15 16:28:29 +01:00
parent 1906ec836c
commit b22b1dea21
4 changed files with 87 additions and 58 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,7 +18,8 @@ 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
} }
} }
@ -53,17 +54,21 @@ 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, system: &mut System, next_thread: Rc<RefCell<Thread>>) { pub fn switch_to(&mut self, next_thread: Rc<RefCell<Thread>>) {
let thread_manager = system.get_thread_manager(); if let Some(tm) = &self.thread_manager {
if let Some(old_thread) = thread_manager.get_g_current_thread() { let rc = Rc::clone(&tm);
thread_manager.thread_save_processor_state(system, Rc::clone(&old_thread)); 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(); // old_thread.save_simulator_state();
if old_thread != &next_thread { if old_thread != &next_thread {
thread_manager.thread_restore_processor_state(system, Rc::clone(&next_thread)); rc.borrow_mut().thread_restore_processor_state(Rc::clone(&next_thread));
// next_thread.restore_simulator_state(); // next_thread.restore_simulator_state();
thread_manager.set_g_current_thread(Option::Some(next_thread)); rc.borrow_mut().set_g_current_thread(Option::Some(next_thread));
} }
} }
} else {
panic!("thread manager shouldn't be none");
}
} }
} }

View File

@ -40,17 +40,22 @@ impl Semaphore {
/// Note that thread_manager::thread_sleep assumes that interrupts are disabled /// Note that thread_manager::thread_sleep assumes that interrupts are disabled
/// when it is called. /// when it is called.
/// ///
/// ### Parameters /// ### Parameters TODO Refaire
/// - *current_thread* the current thread /// - *current_thread* the current thread
/// - *machine* the machine where the threads are executed /// - *machine* the machine where the threads are executed
pub fn p(&mut self, current_thread: Rc<RefCell<Thread>>, system: Rc<RefCell<System>>) { pub fn p(&mut self, system: &mut System) {
let old_status = system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(InterruptOff); let old_status = system.get_machine().interrupt.set_status(InterruptOff);
self.counter -= 1; self.counter -= 1;
if self.counter < 0 { if self.counter < 0 {
self.waiting_queue.push(Rc::clone(&current_thread)); match system.get_thread_manager().get_g_current_thread() {
self.thread_manager.borrow_mut().thread_sleep(current_thread); Some(thread) => {
self.waiting_queue.push(Rc::clone(thread));
system.get_thread_manager().thread_sleep(system, Rc::clone(thread));
},
None => unreachable!("Current thread should not be None")
} }
system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(old_status); }
system.get_machine().interrupt.set_status(old_status);
} }
/// Increment semaphore value, waking up a waiting thread if any. /// Increment semaphore value, waking up a waiting thread if any.
@ -63,13 +68,13 @@ impl Semaphore {
/// ### Parameters /// ### Parameters
/// - **machine** the machine where the threads are executed /// - **machine** the machine where the threads are executed
/// - **scheduler** the scheduler which determine which thread to execute /// - **scheduler** the scheduler which determine which thread to execute
pub fn v(&mut self, system: Rc<RefCell<System>>){ pub fn v(&mut self, system: &mut System){
let old_status = system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(InterruptOff); let old_status = system.get_machine().interrupt.set_status(InterruptOff);
self.counter += 1; self.counter += 1;
if self.waiting_queue.peek() != None { if self.waiting_queue.peek() != None {
system.borrow_mut().get_thread_manager().borrow_mut().g_scheduler.ready_to_run(self.waiting_queue.pop().unwrap()); system.get_thread_manager().g_scheduler.ready_to_run(self.waiting_queue.pop().unwrap());
} }
system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(old_status); system.get_machine().interrupt.set_status(old_status);
} }
} }
@ -111,23 +116,30 @@ impl Lock {
/// ### Parameters /// ### Parameters
/// - **current_thread** the current thread /// - **current_thread** the current thread
/// - **machine** the machine where the threads are executed /// - **machine** the machine where the threads are executed
pub fn acquire(&mut self, current_thread: Option<Rc<RefCell<Thread>>>, system: Rc<RefCell<System>>) { pub fn acquire(&mut self, system: &mut System) {
let old_status = system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(InterruptOff); let old_status = system.get_machine().interrupt.set_status(InterruptOff);
if self.free { if self.free {
self.free = false; self.free = false;
self.owner = current_thread; self.owner = Option::Some(match system.get_thread_manager().get_g_current_thread() {
} else { Some(th) => {
match current_thread { Rc::clone(th)
Some(x) => {
self.waiting_queue.push(Rc::clone(&x));
self.thread_manager.borrow_mut().thread_sleep(x)
}, },
None => () None => unreachable!()
});
} else {
let t = system.get_thread_manager().get_g_current_thread();
match t {
Some(x) => {
let x = Rc::clone(x);
self.waiting_queue.push(Rc::clone(&x));
system.thread_sleep(Rc::clone(&x));
},
None => unreachable!("Current thread should not be None")
} }
} }
system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(old_status); system.get_machine().interrupt.set_status(old_status);
} }
/// Wake up a waiter if necessary, or release it if no thread is waiting. /// Wake up a waiter if necessary, or release it if no thread is waiting.
@ -139,17 +151,16 @@ impl Lock {
/// ### Parameters /// ### Parameters
/// - **machine** the machine where the code is executed /// - **machine** the machine where the code is executed
/// - **scheduler** the scheduler which determine which thread to execute /// - **scheduler** the scheduler which determine which thread to execute
pub fn release(&mut self, system: Rc<RefCell<System>>, current_thread: Rc<RefCell<Thread>>) { pub fn release(&mut self, system: &mut System) {
let old_status = system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(InterruptOff); let old_status = system.get_machine().interrupt.set_status(InterruptOff);
if self.held_by_current_thread(current_thread) { match system.get_thread_manager().get_g_current_thread() {
Some(thread) => {
if self.held_by_current_thread(system) {
if self.waiting_queue.peek() != None { if self.waiting_queue.peek() != None {
self.owner = Some(self.waiting_queue.pop().unwrap()); self.owner = Some(self.waiting_queue.pop().unwrap());
let sys = system.borrow_mut();
let tm = sys.get_thread_manager();
let scheduler = &mut tm.borrow_mut().g_scheduler;
match &self.owner { match &self.owner {
Some(x) => scheduler.ready_to_run(Rc::clone(&x)), Some(x) => system.get_thread_manager().g_scheduler.ready_to_run(Rc::clone(&x)),
None => () None => ()
} }
} else { } else {
@ -157,13 +168,20 @@ impl Lock {
self.owner = None; self.owner = None;
} }
} }
}
system.borrow_mut().get_g_machine().borrow_mut().interrupt.set_status(old_status); None => ()
} }
pub fn held_by_current_thread(&mut self, current_thread: Rc<RefCell<Thread>>) -> bool { system.get_machine().interrupt.set_status(old_status);
}
pub fn held_by_current_thread(&mut self, system: &mut System) -> bool {
match &self.owner { match &self.owner {
Some(x) => Rc::ptr_eq(&x, &current_thread), Some(x) =>
match system.get_thread_manager().get_g_current_thread() {
Some(thread) => Rc::ptr_eq(&x, thread),
None => false
}
None => false None => false
} }
} }
@ -195,11 +213,11 @@ impl Condition {
/// ### Parameters /// ### Parameters
/// - **current_thread** the current thread /// - **current_thread** the current thread
/// - **machine** the machine where threads are executed /// - **machine** the machine where threads are executed
pub fn wait(&mut self, current_thread: Rc<RefCell<Thread>>, machine: &mut Machine) { pub fn wait(&mut self, current_thread: Rc<RefCell<Thread>>, machine: &mut Machine, system: &mut System) {
let old_status = machine.interrupt.set_status(InterruptOff); let old_status = machine.interrupt.set_status(InterruptOff);
self.waiting_queue.push(Rc::clone(&current_thread)); self.waiting_queue.push(Rc::clone(&current_thread));
self.thread_manager.borrow_mut().thread_sleep(current_thread); self.thread_manager.borrow_mut().thread_sleep(system, current_thread);
machine.interrupt.set_status(old_status); machine.interrupt.set_status(old_status);
} }

View File

@ -6,7 +6,7 @@ use std::{cell::RefCell, rc::Rc};
use crate::simulator::machine::Machine; use crate::simulator::machine::Machine;
use super::thread_manager::ThreadManager; use super::{thread_manager::ThreadManager, thread::Thread};
/// This macro properly initializes the system /// This macro properly initializes the system
#[macro_export] #[macro_export]
@ -46,17 +46,23 @@ impl System {
} }
} }
/// Sets a thread asleep
///
pub fn thread_sleep(&mut self, thread: Rc<RefCell<Thread>>) {
&self.thread_manager.thread_sleep(self, thread);
}
// 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(&mut self) -> &mut Machine {
&self.machine &mut self.machine
} }
pub fn get_thread_manager(&self) -> &ThreadManager { pub fn get_thread_manager(&mut self) -> &mut ThreadManager {
&self.thread_manager &mut self.thread_manager
} }
// Setters // Setters

View File

@ -70,7 +70,7 @@ impl ThreadManager {
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(system, next_thread); scheduler.switch_to(next_thread);
} }
machine.interrupt.set_status(old_status); machine.interrupt.set_status(old_status);
} }
@ -86,7 +86,7 @@ impl ThreadManager {
machine.interrupt.idle(); 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()));
} }
/// Finish the execution of the thread and prepare its deallocation /// Finish the execution of the thread and prepare its deallocation