use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum CounterAvailability {
Disabled,
Unavailable,
Available,
}
impl CounterAvailability {
pub fn label(self) -> &'static str {
match self {
CounterAvailability::Disabled => "DISABLED",
CounterAvailability::Unavailable => "UNAVAILABLE",
CounterAvailability::Available => "AVAILABLE",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CounterProbe {
pub availability: CounterAvailability,
pub platform: String,
pub limitation: String,
pub fallback: String,
}
pub fn probe_counters() -> CounterProbe {
#[cfg(target_os = "windows")]
{
CounterProbe {
availability: CounterAvailability::Unavailable,
platform: "windows".into(),
limitation: "Unprivileged PMC access is not available on Windows \
(would require elevated ETW/PMC or a driver). Silicera does not request \
privileges."
.into(),
fallback: "wall-clock MeasurementEngine (median / stability flags)".into(),
}
}
#[cfg(target_os = "linux")]
{
CounterProbe {
availability: CounterAvailability::Unavailable,
platform: "linux".into(),
limitation: "This release does not open perf_event_open; enable a future `counters` \
feature once a least-privilege path is validated. Specialization works \
without PMCs."
.into(),
fallback: "wall-clock MeasurementEngine (median / stability flags)".into(),
}
}
#[cfg(not(any(target_os = "windows", target_os = "linux")))]
{
CounterProbe {
availability: CounterAvailability::Disabled,
platform: std::env::consts::OS.into(),
limitation: "No hardware-counter backend for this OS in this release.".into(),
fallback: "wall-clock MeasurementEngine (median / stability flags)".into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn probe_never_panics() {
let p = probe_counters();
assert!(!p.fallback.is_empty());
assert!(matches!(
p.availability,
CounterAvailability::Disabled
| CounterAvailability::Unavailable
| CounterAvailability::Available
));
}
}