use crate::utility::list::List; use crate::kernel::thread::Thread; use crate::utility::system::{g_current_thread, g_thread_to_be_destroyed}; use std::rc::Rc; struct Scheduler<> { ready_list: List } impl Scheduler { /// Constructor /// /// Initilize the list of ready thread pub fn new() -> Self { Self { ready_list: List::new() } } /// Mark a thread as aready, but not necessarily running yet. /// /// Put it in the ready list, for later scheduling onto the CPU. /// /// ## Pamameter /// /// **thread** is the thread to be put on the read list pub fn ready_to_run(&mut self, thread: Thread) { self.ready_list.push_back(thread); } /// Return the next thread to be scheduled onto the CPU. /// If there are no ready threads, return Option::None /// /// Thread is removed from the ready list. /// /// **return** Thread thread to be scheduled pub fn find_next_to_run(&mut self) -> Option { self.ready_list.pop_back() } /// Dispatch the CPU to next_thread. Save the state of the old thread /// and load the state of the new thread. /// /// We assume the state of the previously running thread has already been changed from running to blocked or ready. /// /// Global variable g_current_thread become next_thread /// /// ## Parameter /// /// **next_thread** thread to dispatch to the CPU pub fn switch_to(&self, next_thread: Thread) { let old_thread = Box::clone(&g_current_thread).unwrap(); g_current_thread.check_overflow(); g_current_thread = Box::new(Option::Some(next_thread)); old_thread.save_processor_state(); old_thread.save_simulator_state(); if(old_thread != g_current_thread) { next_thread.restore_processor_state(); next_thread.restore_simulator_state(); } if(g_thread_to_be_destroyed.is_some()) { drop(g_thread_to_be_destroyed.take()); } } }