diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index 514d495..cb73fcc 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -90,21 +90,27 @@ use crate::{ MachineOk, MachineError } + }, + kernel::{ + thread::Thread, + process::Process } }; -use super::{thread::Thread, process::Process}; +/// Using this type alias to simplify struct and method definitions +type ThreadRef = Rc>; + /// # Thread manager /// /// An instance of this struct is responsible for managing threads on behalf of the system #[derive(PartialEq)] pub struct ThreadManager { /// Current running thread - pub g_current_thread: Option>>, + pub g_current_thread: Option, /// The list of alive threads - pub g_alive: List>>, + pub g_alive: List, /// Thread in ready state waiting to become active - ready_list: List>>, + ready_list: List, /// List of objects created by the thread manager (such as Locks and Semaphores) obj_addrs: ObjAddr, /// If true, enables debug mode @@ -131,7 +137,7 @@ impl ThreadManager { /// ## Pamameter /// /// **thread** is the thread to be put on the read list - pub fn ready_to_run(&mut self, thread: Rc>) { + pub fn ready_to_run(&mut self, thread: ThreadRef) { self.ready_list.push(thread); } @@ -141,7 +147,7 @@ impl ThreadManager { /// Thread is removed from the ready list. /// /// **return** Thread thread to be scheduled - pub fn find_next_to_run(&mut self) -> Option>> { + pub fn find_next_to_run(&mut self) -> Option { self.ready_list.pop() } @@ -155,7 +161,7 @@ impl ThreadManager { /// ## Parameter /// /// **next_thread** thread to dispatch to the CPU - pub fn switch_to(&mut self, machine: &mut Machine, next_thread: Rc>) { + pub fn switch_to(&mut self, machine: &mut Machine, next_thread: ThreadRef) { if let Some(old_thread) = self.get_g_current_thread() { let old_thread = old_thread.clone(); self.thread_save_processor_state(machine, old_thread.clone()); @@ -175,7 +181,7 @@ impl ThreadManager { } /// Start a thread, attaching it to a process - pub fn start_thread(&mut self, thread: Rc>, owner: Rc>, func_pc: u64, sp_loc: u64, argument: i64) { + pub fn start_thread(&mut self, thread: ThreadRef, owner: Rc>, func_pc: u64, sp_loc: u64, argument: i64) { let mut thread_m = thread.borrow_mut(); assert_eq!(thread_m.process, Option::None); thread_m.process = Option::Some(Rc::clone(&owner)); @@ -187,7 +193,7 @@ impl ThreadManager { } /// Wait for another thread to finish its execution - pub fn thread_join(&mut self, machine: &mut Machine, waiter: Rc>, waiting_for: Rc>) { + pub fn thread_join(&mut self, machine: &mut Machine, waiter: ThreadRef, waiting_for: ThreadRef) { let waiting_for = Rc::clone(&waiting_for); while self.get_g_alive().contains(&waiting_for) { self.debug(format!("Joining \"{}\" to \"{}\"", waiter.borrow().get_name(), waiting_for.borrow().get_name())); @@ -198,7 +204,7 @@ impl ThreadManager { /// Relinquish the CPU if any other thread is runnable. /// /// Cannot use yield as a function name -> reserved name in rust - pub fn thread_yield(&mut self, machine: &mut Machine, thread: Rc>) { + pub fn thread_yield(&mut self, machine: &mut Machine, thread: ThreadRef) { let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff); self.debug(format!("Yeilding thread: {}", thread.borrow().get_name())); @@ -212,7 +218,7 @@ impl ThreadManager { } /// Put the thread to sleep and relinquish the processor - pub fn thread_sleep(&mut self, machine: &mut Machine, thread: Rc>) { + pub fn thread_sleep(&mut self, machine: &mut Machine, thread: ThreadRef) { debug_assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread); debug_assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff); @@ -227,7 +233,7 @@ impl ThreadManager { } /// Finish the execution of the thread and prepare its deallocation - pub fn thread_finish(&mut self, machine: &mut Machine, thread: Rc>) { + pub fn thread_finish(&mut self, machine: &mut Machine, thread: ThreadRef) { let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); assert!(self.g_alive.remove(Rc::clone(&thread))); self.debug(format!("Sleeping thread {}", thread.borrow().get_name())); @@ -237,7 +243,7 @@ impl ThreadManager { } /// Save the CPU state of a user program on a context switch. - pub fn thread_save_processor_state(&mut self, machine: &mut Machine, thread: Rc>) { + pub fn thread_save_processor_state(&mut self, machine: &mut Machine, thread: ThreadRef) { let mut t = thread.borrow_mut(); for i in 0..NUM_INT_REGS { t.thread_context.int_registers[i] = machine.read_int_register(i); @@ -249,7 +255,7 @@ impl ThreadManager { } /// Restore the CPU state of a user program on a context switch. - pub fn thread_restore_processor_state(&self, machine: &mut Machine, thread: Rc>) { + pub fn thread_restore_processor_state(&self, machine: &mut Machine, thread: ThreadRef) { let t: Ref<_> = thread.borrow(); for i in 0..NUM_INT_REGS { machine.write_int_register(i, t.thread_context.int_registers[i]); @@ -372,17 +378,17 @@ impl ThreadManager { } /// Currently running thread - pub fn get_g_current_thread(&mut self) -> &Option>> { + pub fn get_g_current_thread(&mut self) -> &Option { &self.g_current_thread } /// List of alive threads - pub fn get_g_alive(&mut self) -> &mut List>> { + pub fn get_g_alive(&mut self) -> &mut List { &mut self.g_alive } /// Set currently running thread - pub fn set_g_current_thread(&mut self, thread: Option>>) { + pub fn set_g_current_thread(&mut self, thread: Option) { self.g_current_thread = thread }