//! Diagnostic probe for RFC 007 on a target box. Measures, in order: //! 1. TSC frequency against `Instant` (the crate assumes 3 GHz). //! 2. TSC sanity under actor migration: distribution of wall time actually //! spent in `burn_us(400)` across many runs — a bimodal/short tail means //! cross-core TSC offsets are cutting burns short. //! 3. Pipeline stage rates with no experiment running (who is the real //! bottleneck?). //! 4. The same rates during a 50% experiment on `background-compaction` //! (a correct implementation must slow every stage; an off-critical-path //! target must reduce end-to-end throughput proportionally). //! //! Run: cargo run --release --example causal_probe --features smarm-causal use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant}; fn burn_us(us: u64) { let cycles = us * 3_000; let start = smarm::preempt::rdtsc(); while smarm::preempt::rdtsc().saturating_sub(start) < cycles { smarm::check!(); } } fn main() { // 1. TSC calibration (plain OS thread, before the runtime starts). let c0 = smarm::preempt::rdtsc(); let t0 = Instant::now(); std::thread::sleep(Duration::from_millis(200)); let hz = (smarm::preempt::rdtsc() - c0) as f64 / t0.elapsed().as_secs_f64(); println!("tsc_hz: {:.3e} (crate assumes 3.0e9)", hz); smarm::init(smarm::Config::default()).run(move || { // 2. burn_us(400) wall-time distribution inside a migrating actor. let h = smarm::spawn(|| { let mut samples: Vec = (0..500) .map(|_| { let t = Instant::now(); burn_us(400); t.elapsed().as_micros() as u64 }) .collect(); samples.sort_unstable(); println!( "burn_us(400) wall us: min {} p10 {} p50 {} p90 {} max {}", samples[0], samples[50], samples[250], samples[450], samples[499] ); }); h.join().unwrap(); // 3+4. Pipeline with per-stage counters. let stop = Arc::new(AtomicBool::new(false)); let produced = Arc::new(AtomicU64::new(0)); let reserved = Arc::new(AtomicU64::new(0)); let notified = Arc::new(AtomicU64::new(0)); let (tx_ab, rx_ab) = smarm::channel::(); let (tx_bc, rx_bc) = smarm::channel::(); let stop_p = stop.clone(); let produced2 = produced.clone(); let producer = smarm::spawn(move || { let mut i = 0u64; while !stop_p.load(Ordering::Relaxed) { { let _g = smarm::causal_site!("serialize"); burn_us(200); } if tx_ab.send(i).is_err() { break; } produced2.fetch_add(1, Ordering::Relaxed); i += 1; } }); let reserved2 = reserved.clone(); let reserve = smarm::spawn(move || { while let Ok(item) = rx_ab.recv() { { let _g = smarm::causal_site!("reserve"); burn_us(400); } reserved2.fetch_add(1, Ordering::Relaxed); if tx_bc.send(item).is_err() { break; } } }); let notified2 = notified.clone(); let notify = smarm::spawn(move || { while rx_bc.recv().is_ok() { { let _g = smarm::causal_site!("notify"); burn_us(50); } notified2.fetch_add(1, Ordering::Relaxed); smarm::progress!("orders-processed"); } }); let stop_bg = stop.clone(); let background = smarm::spawn(move || { while !stop_bg.load(Ordering::Relaxed) { let _g = smarm::causal_site!("background-compaction"); burn_us(500); } }); smarm::sleep(Duration::from_millis(300)); let window = |label: &str| { let (p0, r0, n0) = ( produced.load(Ordering::Relaxed), reserved.load(Ordering::Relaxed), notified.load(Ordering::Relaxed), ); let d0 = smarm::causal::global_delay_cycles(); let t = Instant::now(); smarm::sleep(Duration::from_millis(700)); let secs = t.elapsed().as_secs_f64(); println!( "{label}: produced {:.0}/s reserved {:.0}/s notified {:.0}/s injected {:.0}ms(assumed-3GHz)", (produced.load(Ordering::Relaxed) - p0) as f64 / secs, (reserved.load(Ordering::Relaxed) - r0) as f64 / secs, (notified.load(Ordering::Relaxed) - n0) as f64 / secs, (smarm::causal::global_delay_cycles() - d0) as f64 / 3.0e9 * 1e3, ); }; window("no-experiment "); smarm::causal::begin_experiment_for_test("background-compaction", 50); window("bg-comp @ 50% "); smarm::causal::end_experiment_for_test(); window("post-experiment"); stop.store(true, Ordering::Relaxed); producer.join().unwrap(); reserve.join().unwrap(); notify.join().unwrap(); background.join().unwrap(); }); }