use std::any::{Any, TypeId}; use std::collections::HashMap; use std::sync::Arc; use std::thread::JoinHandle; use std::time::Duration; use crate::asm::data::literal::Addr; use crate::asm::instr::op::EvalRes; use crate::runtime::frame::{CallStack, StackFrame}; use crate::runtime::program::Program; const CYCLE_TIME: Duration = Duration::from_millis(0); //const CYCLE_TIME : Duration = Duration::from_millis(100); #[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] pub struct ThreadToken(pub u32); pub struct RunThread { /// Thread ID pub id: ThreadToken, /// Active stack frame pub frame: StackFrame, /// Call stack pub call_stack: CallStack, /// Program to run pub program: Arc, /// Extension data ext_data: HashMap>, } impl RunThread { pub fn new(id: ThreadToken, program: Arc, pc: Addr, args: &[u64]) -> Self { let sf = StackFrame::new(pc, args); Self { id, frame: sf, call_stack: vec![], program, ext_data: Default::default(), } } pub fn start(self) -> JoinHandle<()> { std::thread::spawn(move || { self.run(); }) } fn run(mut self) { 'run: loop { match self.eval_op() { Ok(EvalRes { cycles, advance }) => { std::thread::sleep(CYCLE_TIME * (cycles as u32)); debug!("Step {}; Status = {}", advance, self.frame.status); self.frame.pc.advance(advance); } Err(e) => { error!("Fault: {:?}", e); break 'run; } } } } pub fn ext_mut(&mut self) -> &mut T { if !self.ext_data.contains_key(&TypeId::of::()) { self.ext_data.insert(TypeId::of::(), Box::new(T::default())); } self.ext_data.get_mut(&TypeId::of::()).unwrap() .downcast_mut().unwrap() } }