#![cfg(all(feature = "tsc", any(target_arch = "x86_64", target_arch = "aarch64")))]
#![forbid(unsafe_code)]
use clock_kit::calibrated::{calibrate, CalibratedClock};
use clock_kit::{Clock, ClockSource};
use std::time::{Duration, Instant};
#[test]
fn tsc_read_matches_instant_within_tolerance() {
let clock = CalibratedClock::new(50_000);
if clock.source() == ClockSource::Instant || clock.source() == ClockSource::LibcMono {
eprintln!("skipping TSC comparison: calibrated clock fell back");
return;
}
assert!(calibrate(50_000).is_ok());
let start = clock.now();
let instant_start = Instant::now();
std::thread::sleep(Duration::from_millis(20));
let instant_elapsed = instant_start.elapsed();
let end = clock.now();
let inst_ns = u64::try_from(instant_elapsed.as_nanos()).unwrap_or(u64::MAX);
let tsc_elapsed = end.mono - start.mono;
let tol = instant_elapsed.mul_f64(0.10) + Duration::from_millis(1);
let tsc = Duration::from_nanos(tsc_elapsed);
#[allow(clippy::unchecked_time_subtraction)]
let (diff, bigger) = if tsc > instant_elapsed {
(tsc - instant_elapsed, "counter")
} else {
(instant_elapsed - tsc, "instant")
};
assert!(
diff <= tol,
"{bigger} ran long: counter {tsc_elapsed} ns vs instant {inst_ns} ns (diff {diff:?})"
);
assert!(
clock.source() == ClockSource::Tsc || clock.source() == ClockSource::Cntvct,
"calibrated clock must report its counter"
);
}