Shadow the hedgehog
This commit is contained in:
parent
b22b1dea21
commit
6dd0cbcc87
@ -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() {
|
// old_thread.save_simulator_state();
|
||||||
rc.borrow_mut().thread_save_processor_state(Rc::clone(&old_thread));
|
|
||||||
// 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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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(¤t_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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user