|
|
@ -8,36 +8,58 @@ use crate::asm::data::literal::Addr; |
|
|
|
use crate::asm::instr::op::EvalRes; |
|
|
|
use crate::asm::instr::op::EvalRes; |
|
|
|
use crate::runtime::frame::{CallStack, StackFrame}; |
|
|
|
use crate::runtime::frame::{CallStack, StackFrame}; |
|
|
|
use crate::runtime::program::Program; |
|
|
|
use crate::runtime::program::Program; |
|
|
|
|
|
|
|
use crate::runtime::fault::Fault; |
|
|
|
const CYCLE_TIME: Duration = Duration::from_millis(0); |
|
|
|
|
|
|
|
//const CYCLE_TIME : Duration = Duration::from_millis(100);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] |
|
|
|
#[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] |
|
|
|
pub struct ThreadToken(pub u32); |
|
|
|
pub struct ThreadToken(pub u32); |
|
|
|
|
|
|
|
|
|
|
|
pub struct RunThread { |
|
|
|
pub struct RunThread { |
|
|
|
|
|
|
|
pub(crate) info: ThreadInfo, |
|
|
|
|
|
|
|
pub(crate) state: RunState, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub struct ThreadInfo { |
|
|
|
/// Thread ID
|
|
|
|
/// Thread ID
|
|
|
|
pub id: ThreadToken, |
|
|
|
pub id: ThreadToken, |
|
|
|
|
|
|
|
/// Program to run
|
|
|
|
|
|
|
|
pub program: Arc<Program>, |
|
|
|
|
|
|
|
/// Program to run
|
|
|
|
|
|
|
|
pub cycle_time: Duration, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub struct RunState { |
|
|
|
/// Active stack frame
|
|
|
|
/// Active stack frame
|
|
|
|
pub frame: StackFrame, |
|
|
|
pub frame: StackFrame, |
|
|
|
/// Call stack
|
|
|
|
/// Call stack
|
|
|
|
pub call_stack: CallStack, |
|
|
|
pub call_stack: CallStack, |
|
|
|
/// Program to run
|
|
|
|
|
|
|
|
pub program: Arc<Program>, |
|
|
|
|
|
|
|
/// Extension data
|
|
|
|
/// Extension data
|
|
|
|
ext_data: HashMap<TypeId, Box<dyn Any + Send>>, |
|
|
|
ext_data: HashMap<TypeId, Box<dyn Any + Send>>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl RunState { |
|
|
|
|
|
|
|
pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T { |
|
|
|
|
|
|
|
if !self.ext_data.contains_key(&TypeId::of::<T>()) { |
|
|
|
|
|
|
|
self.ext_data.insert(TypeId::of::<T>(), Box::new(T::default())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.ext_data.get_mut(&TypeId::of::<T>()).unwrap() |
|
|
|
|
|
|
|
.downcast_mut().unwrap() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl RunThread { |
|
|
|
impl RunThread { |
|
|
|
pub fn new(id: ThreadToken, program: Arc<Program>, pc: Addr, args: &[u64]) -> Self { |
|
|
|
pub fn new(id: ThreadToken, program: Arc<Program>, pc: Addr, args: &[u64]) -> Self { |
|
|
|
let sf = StackFrame::new(pc, args); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Self { |
|
|
|
Self { |
|
|
|
|
|
|
|
info: ThreadInfo { |
|
|
|
id, |
|
|
|
id, |
|
|
|
frame: sf, |
|
|
|
|
|
|
|
call_stack: vec![], |
|
|
|
|
|
|
|
program, |
|
|
|
program, |
|
|
|
|
|
|
|
cycle_time: Duration::default(), |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
state: RunState { |
|
|
|
|
|
|
|
frame: StackFrame::new(pc, args), |
|
|
|
|
|
|
|
call_stack: vec![], |
|
|
|
ext_data: Default::default(), |
|
|
|
ext_data: Default::default(), |
|
|
|
|
|
|
|
}, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -50,12 +72,17 @@ impl RunThread { |
|
|
|
fn run(mut self) { |
|
|
|
fn run(mut self) { |
|
|
|
'run: loop { |
|
|
|
'run: loop { |
|
|
|
match self.eval_op() { |
|
|
|
match self.eval_op() { |
|
|
|
Ok(EvalRes { |
|
|
|
Ok(EvalRes { cycles, advance }) => { |
|
|
|
cycles, advance |
|
|
|
std::thread::sleep(self.info.cycle_time * (cycles as u32)); |
|
|
|
}) => { |
|
|
|
trace!("Step {}; Status = {}", advance, self.state.frame.status); |
|
|
|
std::thread::sleep(CYCLE_TIME * (cycles as u32)); |
|
|
|
self.state.frame.pc.advance(advance); |
|
|
|
trace!("Step {}; Status = {}", advance, self.frame.status); |
|
|
|
if self.state.frame.status.invalid { |
|
|
|
self.frame.pc.advance(advance); |
|
|
|
warn!("Operation failed with INVALID status!"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Err(Fault::Halt) => { |
|
|
|
|
|
|
|
info!("Program ended."); |
|
|
|
|
|
|
|
break 'run; |
|
|
|
} |
|
|
|
} |
|
|
|
Err(e) => { |
|
|
|
Err(e) => { |
|
|
|
error!("Fault: {:?}", e); |
|
|
|
error!("Fault: {:?}", e); |
|
|
@ -64,13 +91,4 @@ impl RunThread { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T { |
|
|
|
|
|
|
|
if !self.ext_data.contains_key(&TypeId::of::<T>()) { |
|
|
|
|
|
|
|
self.ext_data.insert(TypeId::of::<T>(), Box::new(T::default())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.ext_data.get_mut(&TypeId::of::<T>()).unwrap() |
|
|
|
|
|
|
|
.downcast_mut().unwrap() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|