Shadow the hedgehog

This commit is contained in:
Samy Solhi 2023-03-15 16:51:57 +01:00
parent b22b1dea21
commit 6dd0cbcc87
4 changed files with 37 additions and 44 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 {
@ -19,7 +19,6 @@ impl Scheduler {
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,16 @@ 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 old_thread = system.get_thread_manager().get_g_current_thread().as_ref().unwrap();
let rc = Rc::clone(&tm); system.get_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 {
rc.borrow_mut().thread_restore_processor_state(Rc::clone(&next_thread)); system.get_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)); system.get_thread_manager().set_g_current_thread(Option::Some(next_thread));
}
}
} else {
panic!("thread manager shouldn't be none");
} }
} }
} }

View File

@ -17,8 +17,6 @@ pub struct Semaphore {
counter:i32, counter:i32,
/// QUeue of Semaphore waiting to be exucated /// QUeue of Semaphore waiting to be exucated
waiting_queue:List<Rc<RefCell<Thread>>>, waiting_queue:List<Rc<RefCell<Thread>>>,
/// Thread manager which managing threads
thread_manager: Rc<RefCell<ThreadManager>>
} }
@ -29,8 +27,8 @@ impl Semaphore {
/// ### Parameters /// ### Parameters
/// - *counter* initial value of counter /// - *counter* initial value of counter
/// - *thread_manager* Thread manager which managing threads /// - *thread_manager* Thread manager which managing threads
pub fn new(counter: i32, thread_manager: Rc<RefCell<ThreadManager>>) -> Semaphore{ pub fn new(counter: i32) -> Semaphore{
Semaphore { counter, waiting_queue: List::new(), thread_manager} Semaphore { counter, waiting_queue: List::new()}
} }
/// Decrement the value, and wait if it becomes < 0. Checking the /// Decrement the value, and wait if it becomes < 0. Checking the
@ -87,8 +85,6 @@ pub struct Lock{
owner: Option<Rc<RefCell<Thread>>>, owner: Option<Rc<RefCell<Thread>>>,
/// The queue of threads waiting for execution /// The queue of threads waiting for execution
waiting_queue:List<Rc<RefCell<Thread>>>, waiting_queue:List<Rc<RefCell<Thread>>>,
/// Thread manager which managing threads
thread_manager: Rc<RefCell<ThreadManager>>,
/// A boolean definig if the lock is free or not /// A boolean definig if the lock is free or not
free: bool free: bool
@ -101,8 +97,8 @@ impl Lock {
/// ///
/// ### Parameters /// ### Parameters
/// - **thread_manager** Thread manager which managing threads /// - **thread_manager** Thread manager which managing threads
pub fn new(thread_manager: Rc<RefCell<ThreadManager>>) -> Lock { pub fn new() -> Lock {
Lock { owner: None, waiting_queue: List::new(), thread_manager, free: true } Lock { owner: None, waiting_queue: List::new(), free: true }
} }
/// Wait until the lock become free. Checking the /// Wait until the lock become free. Checking the
@ -192,8 +188,6 @@ pub struct Condition{
/// The queue of threads waiting for execution /// The queue of threads waiting for execution
waiting_queue:List<Rc<RefCell<Thread>>>, waiting_queue:List<Rc<RefCell<Thread>>>,
/// Thread manager which managing threads
thread_manager: Rc<RefCell<ThreadManager>>,
} }
@ -203,8 +197,8 @@ impl Condition {
/// ///
/// ### Parameters /// ### Parameters
/// - *thread_manager* Thread manager which managing threads /// - *thread_manager* Thread manager which managing threads
pub fn new(thread_manager: Rc<RefCell<ThreadManager>>) -> Condition { pub fn new() -> Condition {
Condition{ waiting_queue: List::new(), thread_manager } Condition{ waiting_queue: List::new()}
} }
/// Block the calling thread (put it in the wait queue). /// Block the calling thread (put it in the wait queue).
@ -213,13 +207,18 @@ 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, system: &mut System) { pub fn wait(&mut self, system: &mut System) {
let old_status = machine.interrupt.set_status(InterruptOff); let old_status = system.get_machine().interrupt.set_status(InterruptOff);
self.waiting_queue.push(Rc::clone(&current_thread)); match system.get_thread_manager().get_g_current_thread() {
self.thread_manager.borrow_mut().thread_sleep(system, current_thread); Some(thread) => {
self.waiting_queue.push(Rc::clone(thread));
system.thread_sleep(Rc::clone(thread));
},
None => unreachable!()
}
machine.interrupt.set_status(old_status); system.get_machine().interrupt.set_status(old_status);
} }
/// Wake up the first thread of the wait queue (if any). /// Wake up the first thread of the wait queue (if any).
@ -228,14 +227,14 @@ impl Condition {
/// ### 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 signal(&mut self, machine: &mut Machine, scheduler: &mut Scheduler) { pub fn signal(&mut self, system: &mut System) {
let old_status = machine.interrupt.set_status(InterruptOff); let old_status = system.get_machine().interrupt.set_status(InterruptOff);
if self.waiting_queue.peek() != None { if self.waiting_queue.peek() != None {
scheduler.ready_to_run(self.waiting_queue.pop().unwrap()); system.get_thread_manager().g_scheduler.ready_to_run(self.waiting_queue.pop().unwrap());
} }
machine.interrupt.set_status(old_status); system.get_machine().interrupt.set_status(old_status);
} }
@ -245,13 +244,13 @@ impl Condition {
/// ### 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 broadcast(&mut self, machine: &mut Machine, scheduler: &mut Scheduler) { pub fn broadcast(&mut self, system: &mut System) {
let old_status = machine.interrupt.set_status(InterruptOff); let old_status = system.get_machine().interrupt.set_status(InterruptOff);
while self.waiting_queue.peek() != None { while self.waiting_queue.peek() != None {
scheduler.ready_to_run(self.waiting_queue.pop().unwrap()); system.get_thread_manager().g_scheduler.ready_to_run(self.waiting_queue.pop().unwrap());
} }
machine.interrupt.set_status(old_status); system.get_machine().interrupt.set_status(old_status);
} }

View File

@ -49,7 +49,7 @@ impl System {
/// Sets a thread asleep /// Sets a thread asleep
/// ///
pub fn thread_sleep(&mut self, thread: Rc<RefCell<Thread>>) { pub fn thread_sleep(&mut self, thread: Rc<RefCell<Thread>>) {
&self.thread_manager.thread_sleep(self, thread); self.thread_manager.thread_sleep(self, thread);
} }
// GETTERS // GETTERS

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(next_thread); scheduler.switch_to(system, 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(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