use std::{cell::RefCell, rc::Rc}; use crate::simulator::machine::Machine; use super::thread_manager::ThreadManager; /// This macro properly initializes the system #[macro_export] macro_rules! init_system { () => {{ let m = Machine::init_machine(); init_system!(m) }}; ($a:expr) => {{ System::new($a) }}; } /// # System /// /// This structure represents the state of the threads running on the operating system. /// It contains references to the following: /// /// - The simulated machine /// - The current running thread /// - The list of active threads /// - The thread to be destroyed next /// - The scheduler which acts upon these threads #[derive(PartialEq)] pub struct System { g_machine: RefCell, thread_manager: Rc> } impl System { /// System constructor pub fn new(machine: Machine) -> System { Self { g_machine: RefCell::new(machine), thread_manager: Rc::new(RefCell::new(ThreadManager::new())) } } /// use thread_manager setter to send it system instance pub fn freeze(this: Rc>) { let copy = Rc::clone(&this); let tm = &this.borrow_mut().thread_manager; tm.borrow_mut().system = Option::Some(copy); ThreadManager::freeze(tm); } // GETTERS /// Returns the Machine /// /// Useful to access RAM, devices, ... pub fn get_g_machine(&self) -> &RefCell { &self.g_machine } // Setters /// Assign a machine to the system pub fn set_g_machine(&mut self, machine: RefCell) { self.g_machine = machine } } #[derive(PartialEq, Debug)] pub enum ObjectType { SemaphoreType, LockType, ConditionType, FileType, ThreadType, InvalidType } #[cfg(test)] mod tests { use crate::{System, Machine}; #[test] fn test_init_system() { init_system!(); } }