use tacet_core::preflight::ResolutionWarning;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum TimerSanityWarning {
NonMonotonic {
violations: usize,
max_jump_cycles: u64,
},
}
impl TimerSanityWarning {
pub fn is_result_undermining(&self) -> bool {
true }
pub fn to_resolution_warning(&self) -> ResolutionWarning {
match self {
TimerSanityWarning::NonMonotonic { .. } => ResolutionWarning::InsufficientResolution {
unique_values: 0,
total_samples: 0,
zero_fraction: 1.0,
timer_resolution_ns: f64::INFINITY,
},
}
}
}
pub fn timer_sanity_check(_timer: &crate::measurement::BoxedTimer) -> Option<TimerSanityWarning> {
let mut violations = 0;
let mut max_jump = 0;
let mut last = crate::measurement::rdtsc();
for _ in 0..1000 {
let current = crate::measurement::rdtsc();
if current < last {
violations += 1;
max_jump = max_jump.max(last - current);
}
last = current;
}
if violations > 0 {
return Some(TimerSanityWarning::NonMonotonic {
violations,
max_jump_cycles: max_jump,
});
}
None
}
#[cfg(test)]
mod tests {
use super::*;
use crate::measurement::{BoxedTimer, Timer};
#[test]
fn test_timer_sanity_check() {
let timer = BoxedTimer::Standard(Timer::new());
let result = timer_sanity_check(&timer);
assert!(
result.is_none(),
"Timer should be monotonic on a working system"
);
}
}