diff --git a/Cargo.lock b/Cargo.lock index 8a5d033..224f89d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,6 +179,7 @@ dependencies = [ "num-traits", "parking_lot", "sexp", + "spin_sleep", "thiserror", ] @@ -898,9 +899,6 @@ dependencies = [ [[package]] name = "sexp" version = "1.1.4" -dependencies = [ - "log", -] [[package]] name = "sha-1" @@ -933,6 +931,16 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" +[[package]] +name = "spin_sleep" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a98101bdc3833e192713c2af0b0dd2614f50d1cf1f7a97c5221b7aac052acc7" +dependencies = [ + "once_cell", + "winapi", +] + [[package]] name = "strsim" version = "0.8.0" diff --git a/crsn/Cargo.toml b/crsn/Cargo.toml index 41fa0ef..5a18546 100644 --- a/crsn/Cargo.toml +++ b/crsn/Cargo.toml @@ -14,3 +14,4 @@ log = "0.4.11" num-traits = "0.2.12" parking_lot = "0.11.0" nudge = "0.2.1" +spin_sleep = "1.0.0" diff --git a/crsn/crsn-sexp/Cargo.toml b/crsn/crsn-sexp/Cargo.toml index 6c03b9f..3c844bf 100644 --- a/crsn/crsn-sexp/Cargo.toml +++ b/crsn/crsn-sexp/Cargo.toml @@ -11,4 +11,3 @@ description = "A small, simple, self-contained, s-expression parser and pretty-p license = "MIT" [dependencies] -log = "0.4.11" diff --git a/crsn/crsn-sexp/src/lib.rs b/crsn/crsn-sexp/src/lib.rs index 24485c4..5a360ae 100644 --- a/crsn/crsn-sexp/src/lib.rs +++ b/crsn/crsn-sexp/src/lib.rs @@ -4,9 +4,6 @@ #![deny(unsafe_code)] -#[macro_use] -extern crate log; - use std::borrow::Cow; use std::fmt; use std::str::{self, FromStr}; diff --git a/crsn/src/runtime/run_thread.rs b/crsn/src/runtime/run_thread.rs index 9755cb9..baecf59 100644 --- a/crsn/src/runtime/run_thread.rs +++ b/crsn/src/runtime/run_thread.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use std::thread::JoinHandle; -use std::time::Duration; +use std::time::{Duration}; pub use info::ThreadInfo; pub use state::RunState; @@ -66,11 +66,16 @@ impl RunThread { /// Start synchronously pub fn run(mut self) { + let mut loop_helper = spin_sleep::LoopHelper::builder() + .build_with_target_rate(1.0/self.info.cycle_time.as_secs_f64()); + + loop_helper.loop_start(); 'run: loop { match self.eval_op() { Ok(EvalRes { cycles, advance }) => { - if cycles > 0 { - std::thread::sleep(self.info.cycle_time * (cycles as u32)); + for _ in 0..cycles { + loop_helper.loop_sleep(); + loop_helper.loop_start(); } trace!("Step {}; Status = {}", advance, self.state.frame.status); self.state.frame.pc.advance(advance); diff --git a/launcher/src/main.rs b/launcher/src/main.rs index 956c3f2..ea0a278 100644 --- a/launcher/src/main.rs +++ b/launcher/src/main.rs @@ -92,22 +92,8 @@ impl AppConfig for Config { clap::Arg::with_name("cycle") .long("cycle") .short("C") - .value_name("MILLIS") - .help("Cycle time (ms)") - .validator(|s| { - let t = s.trim(); - if t.is_empty() { - Err("cycle time requires an argument".into()) - } else { - if t.chars() - .find(|c| !c.is_ascii_digit()) - .is_some() { - Err("cycle time requires an integer number".into()) - } else { - Ok(()) - } - } - }) + .value_name("MICROS") + .help("Cycle time (us, append \"s\" or \"ms\" for coarser time)") .takes_value(true), ) } @@ -115,8 +101,23 @@ impl AppConfig for Config { fn configure(mut self, clap: &ArgMatches) -> anyhow::Result { self.program_file = clap.value_of("input").unwrap().to_string(); self.assemble_only = clap.is_present("asm-only"); - if let Some(c) = clap.value_of("cycle") { - self.cycle_time = Duration::from_millis(c.parse().unwrap()); + if let Some(t) = clap.value_of("cycle") { + let (t, mul) = if t.ends_with("us") { + (&t[..(t.len()-2)], 1) + } else if t.ends_with("ms") { + (&t[..(t.len()-2)], 1000) + } else if t.ends_with("m") { + (&t[..(t.len()-1)], 1000) + } else if t.ends_with("u") { + (&t[..(t.len()-1)], 1) + } else if t.ends_with("s") { + (&t[..(t.len()-1)], 1000_000) + } else { + (t, 1) + }; + + self.cycle_time = Duration::from_micros(t.parse::().expect("parse -C value") * mul); + println!("ct = {:?}", self.cycle_time); } Ok(self) }