Skip to content

Commit

Permalink
feat: Check if VM supports TSC
Browse files Browse the repository at this point in the history
  • Loading branch information
ariesdevil committed Oct 5, 2024
1 parent 8826c84 commit e5b7459
Showing 1 changed file with 45 additions and 3 deletions.
48 changes: 45 additions & 3 deletions src/tsc_now.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use std::cell::UnsafeCell;
use std::fs::read_to_string;
use std::io::ErrorKind;
use std::time::Instant;

static TSC_STATE: TSCState = TSCState {
Expand Down Expand Up @@ -92,10 +93,51 @@ impl TSCLevel {
/// rely on the result to say tsc is stable so that no need to
/// sync TSCs by ourselves.
fn is_tsc_stable() -> bool {
let clock_source =
read_to_string("/sys/devices/system/clocksource/clocksource0/available_clocksource");
has_invariant_tsc() || clock_source_has_tsc()
}

fn clock_source_has_tsc() -> bool {
#[cfg(target_os = "linux")]
{
let clock_sources = [
"/sys/devices/system/clocksource/clocksource0/current_clocksource",
"/sys/devices/system/clocksource/clocksource0/available_clocksource",
];

for &path in &clock_sources {
match read_to_string(path) {
Ok(content) => {
if content.contains("tsc") {
return true;
}
}
Err(e) if e.kind() == ErrorKind::NotFound => continue,
Err(_) => return false,
}
}
false
}

#[cfg(not(target_os = "linux"))]
false
}

/// Invariant TSC could make sure TSC got synced among multi CPUs.
/// They will be reset at same time, and run in same frequency.
/// But in some VM, the max Extended Function in CPUID is < 0x80000007,
/// we should enable TSC if the system clock source is TSC.
#[inline]
fn has_invariant_tsc() -> bool {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
unsafe {
use core::arch::x86_64::__cpuid;
let cpuid_invariant_tsc_bts = 1 << 8;
__cpuid(0x80000000).eax >= 0x80000007
&& __cpuid(0x80000007).edx & cpuid_invariant_tsc_bts != 0
}

clock_source.map(|s| s.contains("tsc")).unwrap_or(false)
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
false
}

/// Returns (1) cycles per second and (2) cycles from anchor.
Expand Down

0 comments on commit e5b7459

Please sign in to comment.