#[cfg(target_arch = "aarch64")]
use core::arch::asm;
#[cfg(all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))]
use core::arch::asm;
#[cfg(target_arch = "aarch64")]
pub fn get_aarch64_counter_freq_hz() -> u64 {
#[cfg(feature = "std")]
{
use std::sync::OnceLock;
static VALIDATED_FREQ: OnceLock<u64> = OnceLock::new();
*VALIDATED_FREQ.get_or_init(|| {
let cntfrq: u64;
unsafe {
asm!("mrs {}, cntfrq_el0", out(reg) cntfrq);
}
if !is_reasonable_aarch64_freq(cntfrq) {
eprintln!(
"[tacet-core] WARNING: CNTFRQ_EL0 returned suspicious value: {} Hz",
cntfrq
);
eprintln!("[tacet-core] Calibrating ARM64 counter frequency...");
return calibrate_aarch64_frequency();
}
let calibrated = calibrate_aarch64_frequency();
let ratio = calibrated as f64 / cntfrq as f64;
if !(0.9..=1.1).contains(&ratio) {
eprintln!(
"[tacet-core] WARNING: CNTFRQ_EL0 ({} Hz / {:.2} MHz) differs from calibrated frequency ({} Hz / {:.2} MHz) by {:.1}%",
cntfrq, cntfrq as f64 / 1e6,
calibrated, calibrated as f64 / 1e6,
(ratio - 1.0) * 100.0
);
eprintln!(
"[tacet-core] This typically indicates virtualization (VM/CI) with misconfigured timers."
);
eprintln!(
"[tacet-core] Using calibrated frequency: {} Hz ({:.2} MHz)",
calibrated, calibrated as f64 / 1e6
);
return calibrated;
}
cntfrq
})
}
#[cfg(not(feature = "std"))]
{
let freq: u64;
unsafe {
asm!("mrs {}, cntfrq_el0", out(reg) freq);
}
if is_reasonable_aarch64_freq(freq) {
freq
} else {
24_000_000 }
}
}
#[cfg(target_arch = "aarch64")]
#[inline]
fn is_reasonable_aarch64_freq(freq: u64) -> bool {
(1_000_000..=10_000_000_000).contains(&freq)
}
#[cfg(all(feature = "std", target_arch = "aarch64", target_os = "linux"))]
fn detect_aarch64_platform_freq() -> Option<u64> {
let cpuinfo = std::fs::read_to_string("/proc/cpuinfo").ok()?;
let cpuinfo_lower = cpuinfo.to_lowercase();
if cpuinfo_lower.contains("neoverse") || cpuinfo_lower.contains("graviton") {
return Some(1_000_000_000); }
if cpuinfo_lower.contains("raspberry pi 4") || cpuinfo_lower.contains("bcm2711") {
return Some(54_000_000); }
None
}
#[cfg(all(feature = "std", target_arch = "aarch64"))]
#[allow(dead_code)]
fn calibrate_aarch64_frequency() -> u64 {
use std::time::{Duration, Instant};
const SAMPLES: usize = 5;
const SLEEP_MS: u64 = 20;
let mut frequencies = Vec::with_capacity(SAMPLES);
for _ in 0..SAMPLES {
let start_cnt: u64;
unsafe {
asm!("mrs {}, cntvct_el0", out(reg) start_cnt);
}
let start_instant = Instant::now();
std::thread::sleep(Duration::from_millis(SLEEP_MS));
let end_cnt: u64;
unsafe {
asm!("mrs {}, cntvct_el0", out(reg) end_cnt);
}
let elapsed_ns = start_instant.elapsed().as_nanos() as u64;
let cnt_delta = end_cnt.wrapping_sub(start_cnt);
let freq = ((cnt_delta as u128 * 1_000_000_000) / elapsed_ns as u128) as u64;
if is_reasonable_aarch64_freq(freq) {
frequencies.push(freq);
}
}
if frequencies.is_empty() {
eprintln!("[tacet-core] WARNING: ARM64 calibration failed. Using 24MHz estimate.");
return 24_000_000;
}
frequencies.sort_unstable();
let median = frequencies[frequencies.len() / 2];
eprintln!(
"[tacet-core] ARM64 counter frequency calibrated to {:.2} MHz",
median as f64 / 1_000_000.0
);
median
}
#[cfg(all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))]
pub fn get_x86_64_tsc_freq_hz() -> u64 {
#[cfg(feature = "std")]
{
use std::sync::OnceLock;
static VALIDATED_FREQ: OnceLock<u64> = OnceLock::new();
*VALIDATED_FREQ.get_or_init(|| {
#[cfg(target_os = "linux")]
if let Some(freq) = get_tsc_freq_linux() {
return freq;
}
#[cfg(target_os = "macos")]
if let Some(freq) = get_tsc_freq_macos() {
return freq;
}
calibrate_tsc_frequency()
})
}
#[cfg(not(feature = "std"))]
{
3_000_000_000
}
}
#[cfg(all(feature = "std", target_arch = "x86_64", target_os = "linux"))]
fn get_tsc_freq_linux() -> Option<u64> {
if let Ok(content) = std::fs::read_to_string("/sys/devices/system/cpu/cpu0/tsc_freq_khz") {
if let Ok(khz) = content.trim().parse::<u64>() {
let freq = khz * 1000;
if is_reasonable_tsc_freq(freq) {
return Some(freq);
}
}
}
if has_invariant_tsc() {
if let Some(freq) = get_cpuid_base_freq() {
if is_reasonable_tsc_freq(freq) {
return Some(freq);
}
}
}
None
}
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
fn has_invariant_tsc() -> bool {
let result: u32;
unsafe {
asm!(
"push rbx",
"mov eax, 0x80000007",
"cpuid",
"pop rbx",
out("edx") result,
out("eax") _,
out("ecx") _,
options(nostack)
);
}
(result & (1 << 8)) != 0
}
#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
fn get_cpuid_base_freq() -> Option<u64> {
let max_leaf: u32;
unsafe {
asm!(
"push rbx",
"mov eax, 0",
"cpuid",
"pop rbx",
out("eax") max_leaf,
out("ecx") _,
out("edx") _,
options(nostack)
);
}
if max_leaf < 0x16 {
return None;
}
let base_mhz: u32;
unsafe {
asm!(
"push rbx",
"mov eax, 0x16",
"cpuid",
"pop rbx",
out("eax") base_mhz,
out("ecx") _,
out("edx") _,
options(nostack)
);
}
if base_mhz == 0 {
return None;
}
Some(base_mhz as u64 * 1_000_000)
}
#[cfg(all(feature = "std", target_arch = "x86_64", target_os = "macos"))]
fn get_tsc_freq_macos() -> Option<u64> {
if let Some(freq) = sysctl_read_u64("machdep.tsc.frequency") {
if is_reasonable_tsc_freq(freq) {
return Some(freq);
}
}
if let Some(freq) = sysctl_read_u64("hw.cpufrequency") {
if is_reasonable_tsc_freq(freq) {
return Some(freq);
}
}
None
}
#[cfg(all(feature = "std", target_arch = "x86_64", target_os = "macos"))]
fn sysctl_read_u64(name: &str) -> Option<u64> {
use std::process::Command;
let output = Command::new("sysctl").arg("-n").arg(name).output().ok()?;
if !output.status.success() {
return None;
}
let stdout = String::from_utf8_lossy(&output.stdout);
stdout.trim().parse::<u64>().ok()
}
#[cfg(all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))]
#[inline]
fn is_reasonable_tsc_freq(freq: u64) -> bool {
(500_000_000..=10_000_000_000).contains(&freq)
}
#[cfg(all(
feature = "std",
target_arch = "x86_64",
any(target_os = "linux", target_os = "macos")
))]
fn calibrate_tsc_frequency() -> u64 {
use std::time::{Duration, Instant};
eprintln!("[tacet-core] Calibrating TSC frequency (no sysfs/sysctl available)...");
const SAMPLES: usize = 5;
const SLEEP_MS: u64 = 20;
let mut frequencies = Vec::with_capacity(SAMPLES);
for _ in 0..SAMPLES {
let start_tsc = rdtsc();
let start_instant = Instant::now();
std::thread::sleep(Duration::from_millis(SLEEP_MS));
let end_tsc = rdtsc();
let elapsed_ns = start_instant.elapsed().as_nanos() as u64;
let tsc_delta = end_tsc.wrapping_sub(start_tsc);
let freq = ((tsc_delta as u128 * 1_000_000_000) / elapsed_ns as u128) as u64;
if is_reasonable_tsc_freq(freq) {
frequencies.push(freq);
}
}
if frequencies.is_empty() {
eprintln!("[tacet-core] WARNING: TSC calibration failed. Using 3GHz estimate.");
return 3_000_000_000;
}
frequencies.sort_unstable();
let median = frequencies[frequencies.len() / 2];
eprintln!(
"[tacet-core] TSC frequency calibrated to {:.2} GHz",
median as f64 / 1_000_000_000.0
);
median
}
#[cfg(all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))]
#[inline]
fn rdtsc() -> u64 {
let lo: u32;
let hi: u32;
unsafe {
asm!(
"rdtsc",
out("eax") lo,
out("edx") hi,
options(nostack, nomem)
);
}
((hi as u64) << 32) | (lo as u64)
}
pub fn counter_frequency_hz() -> u64 {
#[cfg(target_arch = "aarch64")]
{
get_aarch64_counter_freq_hz()
}
#[cfg(all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))]
{
get_x86_64_tsc_freq_hz()
}
#[cfg(not(any(
target_arch = "aarch64",
all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos"))
)))]
{
0 }
}
pub fn timer_resolution_ns() -> f64 {
let freq = counter_frequency_hz();
if freq == 0 {
f64::INFINITY
} else {
1_000_000_000.0 / freq as f64
}
}