use super::process::Process; use crate::{simulator::machine::{NUM_INT_REGS, NUM_FP_REGS, STACK_REG}, utility::system::ObjectType}; const SIMULATORSTACKSIZE: usize = 32 * 1024; #[derive(PartialEq)] struct SimulatorContext { // todo } #[derive(PartialEq)] struct ThreadContext { pub int_registers: [i64; NUM_INT_REGS], pub float_registers: [i64; NUM_FP_REGS], pc: i64, } #[derive(PartialEq)] pub struct Thread { name: String, process: Option, simulation_context: SimulatorContext, thread_context: ThreadContext, stack_pointer: i32, object_type: ObjectType } impl Thread { pub fn new(name: String) -> Self { Self { name, process: None, simulation_context: SimulatorContext { }, thread_context: ThreadContext { int_registers: [0; NUM_INT_REGS], float_registers: [0; NUM_FP_REGS], pc: 0 }, stack_pointer: 0, object_type: ObjectType::ThreadType } } /// Start a thread, attaching it to a process pub fn start(&mut self, owner: Process, func: i64, arg: i64) -> i32 { self.process = Option::Some(owner); let ptr = 0; // todo addrspace self.init_thread_context(func, ptr, arg); let base_stack_addr: [i8; SIMULATORSTACKSIZE] = [0; SIMULATORSTACKSIZE]; // todo AllocBoundedArray self.init_simulator_context(base_stack_addr); self.process.as_mut().unwrap().num_thread += 1; todo!(); } fn init_thread_context(&mut self, initial_pc_reg: i64, initial_sp: i64, arg: i64) { self.thread_context.pc = initial_pc_reg; self.thread_context.int_registers[10] = arg; self.thread_context.int_registers[STACK_REG] = initial_sp; } /// Wait for another thread to finish its execution pub fn join(&self, id_thread: &Thread) { todo!(); } /// Relinquish the CPU if any other thread is runnable. /// /// Cannot use yield as a function name -> reserved name in rust pub fn t_yield(&self) { todo!(); } /// Put the thread to sleep and relinquish the processor pub fn sleep(&self) { todo!(); } /// Finish the execution of the thread and prepare its deallocation pub fn finish(&self) { todo!(); } /// Check if a thread has overflowed its stack pub fn check_overflow(&self) { todo!(); } pub fn init_simulator_context(&self, base_stack_addr: [i8; SIMULATORSTACKSIZE]) { todo!(); } pub fn save_processor_state(&self) { todo!(); } pub fn restore_processor_state(&self) { todo!(); } pub fn save_simulator_state(&self) { todo!(); } pub fn restore_simulator_state(&self) { todo!(); } pub fn get_name(&self) -> String { self.name.clone() } } impl Drop for Thread { fn drop(&mut self) { self.object_type = ObjectType::InvalidType; todo!(); } }