Croissant Runtime
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
crsn/crsn/src/runtime/run_thread.rs

79 lines
2.2 KiB

use std::sync::Arc;
use std::sync::atomic::AtomicU64;
use std::thread::JoinHandle;
use std::time::Duration;
pub use info::ThreadInfo;
pub use state::RunState;
use crate::asm::data::literal::Addr;
use crate::module::EvalRes;
use crate::runtime::fault::Fault;
use crate::runtime::frame::StackFrame;
use crate::runtime::program::Program;
#[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)]
pub struct ThreadToken(pub u32);
pub struct RunThread {
pub(crate) info: ThreadInfo,
pub(crate) state: RunState,
}
pub mod info;
pub mod state;
pub fn new_uniq() -> Arc<AtomicU64> {
Arc::new(AtomicU64::new(info::UNIQ_BASE))
}
impl RunThread {
pub fn new(id: ThreadToken, uniq: Option<Arc<AtomicU64>>, program: Arc<Program>, pc: Addr, args: &[u64]) -> Self {
Self {
info: ThreadInfo {
id,
uniq: uniq.unwrap_or_else(new_uniq),
program,
cycle_time: Duration::default(),
},
state: RunState {
frame: StackFrame::new(pc, args),
call_stack: vec![],
ext_data: Default::default(),
},
}
}
pub fn set_speed(&mut self, cycle_time: Duration) {
self.info.cycle_time = cycle_time;
}
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(self.info.cycle_time * (cycles as u32));
trace!("Step {}; Status = {}", advance, self.state.frame.status);
self.state.frame.pc.advance(advance);
if self.state.frame.status.invalid {
warn!("Operation failed with INVALID status!");
}
}
Err(Fault::Halt) => {
info!("Program ended.");
break 'run;
}
Err(e) => {
error!("Fault: {:?}", e);
break 'run;
}
}
}
}
}