Skip to content

Commit

Permalink
Remove has_cpuid check
Browse files Browse the repository at this point in the history
It no longer planned for Rust, since CPUID is assumed to be available on
all old x86 Rust targets.
  • Loading branch information
nvzqz committed Nov 1, 2024
1 parent 5212444 commit e83cb7a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 81 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ Versioning](http://semver.org/spec/v2.0.0.html).
- [`CyclesCount`] counter to display cycle throughput as Hertz.
- Track the maximum number of bytes allocated during a benchmark.

### Removed

- Remove `has_cpuid` polyfill due to it no longer being planned for Rust, since
CPUID is assumed to be available on all old x86 Rust targets.

### Fixed

- List generic benchmark type parameter `A<4>` before `A<32>` ([#64]).
Expand Down
87 changes: 6 additions & 81 deletions src/time/timestamp/tsc/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,15 @@ pub(crate) fn end_timestamp() -> u64 {
}

pub(crate) fn frequency() -> Result<u64, TscUnavailable> {
let mut nominal = None;

// If we don't have CPUID, avoid it and assume invariant TSC.
if util::has_cpuid() {
if !util::tsc_is_available() {
return Err(TscUnavailable::MissingInstructions);
}

if !util::tsc_is_invariant() {
return Err(TscUnavailable::VariableFrequency);
}
if !util::tsc_is_available() {
return Err(TscUnavailable::MissingInstructions);
}

nominal = nominal_frequency();
if !util::tsc_is_invariant() {
return Err(TscUnavailable::VariableFrequency);
}

let nominal = nominal_frequency();
let measured = measure::measure_frequency();

// Use the nominal frequency if within 0.1% of the measured frequency.
Expand Down Expand Up @@ -130,75 +124,6 @@ mod util {
unsafe { x86::_mm_lfence() }
}

/// Does the host support the `cpuid` instruction?
///
/// This is a stable polyfill of [`x86::has_cpuid`].
#[inline]
pub fn has_cpuid() -> bool {
// https://doc.rust-lang.org/1.72.0/src/core/stdarch/crates/core_arch/src/x86/cpuid.rs.html#101
#[cfg(target_env = "sgx")]
{
false
}
#[cfg(all(not(target_env = "sgx"), target_arch = "x86_64"))]
{
true
}
#[cfg(all(not(target_env = "sgx"), target_arch = "x86"))]
{
// Optimization for i586 and i686 Rust targets which SSE enabled
// and support cpuid:
#[cfg(target_feature = "sse")]
{
true
}

// If SSE is not enabled, detect whether cpuid is available:
#[cfg(not(target_feature = "sse"))]
unsafe {
// On `x86` the `cpuid` instruction is not always available.
// This follows the approach indicated in:
// http://wiki.osdev.org/CPUID#Checking_CPUID_availability
// https://software.intel.com/en-us/articles/using-cpuid-to-detect-the-presence-of-sse-41-and-sse-42-instruction-sets/
// which detects whether `cpuid` is available by checking whether
// the 21st bit of the EFLAGS register is modifiable or not.
// If it is, then `cpuid` is available.
let result: u32;
std::arch::asm!(
// Read eflags and save a copy of it
"pushfd",
"pop {result}",
"mov {result}, {saved_flags}",
// Flip 21st bit of the flags
"xor $0x200000, {result}",
// Load the modified flags and read them back.
// Bit 21 can only be modified if cpuid is available.
"push {result}",
"popfd",
"pushfd",
"pop {result}",
// Use xor to find out whether bit 21 has changed
"xor {saved_flags}, {result}",
result = out(reg) result,
saved_flags = out(reg) _,
options(nomem, att_syntax),
);
// There is a race between popfd (A) and pushfd (B)
// where other bits beyond 21st may have been modified due to
// interrupts, a debugger stepping through the asm, etc.
//
// Therefore, explicitly check whether the 21st bit
// was modified or not.
//
// If the result is zero, the cpuid bit was not modified.
// If the result is `0x200000` (non-zero), then the cpuid
// was correctly modified and the CPU supports the cpuid
// instruction:
(result & 0x200000) != 0
}
}
}

#[inline]
fn cpuid(leaf: u32) -> x86::CpuidResult {
// SAFETY: `cpuid` is never unsafe to call.
Expand Down

0 comments on commit e83cb7a

Please sign in to comment.