blob: e19c4b8b73e716e6abc834e507f4c9656567b899 [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Run-time feature detection on aarch64 Windows by using IsProcessorFeaturePresent.
//
// As of nightly-2023-01-23, is_aarch64_feature_detected doesn't support run-time detection of FEAT_LSE on Windows.
// https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/std_detect/src/detect/os/windows/aarch64.rs
// https://github.com/rust-lang/stdarch/pull/1373
//
// Refs: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
include!("common.rs");
// windows-sys requires Rust 1.48
#[allow(clippy::upper_case_acronyms)]
mod ffi {
pub(crate) type DWORD = u32;
pub(crate) type BOOL = i32;
pub(crate) const FALSE: BOOL = 0;
// Defined in winnt.h of Windows SDK.
pub(crate) const PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE: DWORD = 34;
extern "system" {
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
pub(crate) fn IsProcessorFeaturePresent(ProcessorFeature: DWORD) -> BOOL;
}
}
#[cold]
fn _detect(info: &mut CpuInfo) {
// SAFETY: calling IsProcessorFeaturePresent is safe, and FALSE is also
// returned if the HAL does not support detection of the specified feature.
if unsafe {
ffi::IsProcessorFeaturePresent(ffi::PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE) != ffi::FALSE
} {
info.set(CpuInfo::HAS_LSE);
}
}
#[allow(
clippy::alloc_instead_of_core,
clippy::std_instead_of_alloc,
clippy::std_instead_of_core,
clippy::undocumented_unsafe_blocks,
clippy::wildcard_imports
)]
#[cfg(test)]
mod tests {
use super::*;
// Static assertions for FFI bindings.
// This checks that FFI bindings defined in this crate and FFI bindings defined
// in windows-sys have compatible signatures (or the same values if constants).
// Since this is static assertion, we can detect problems with
// `cargo check --tests --target <target>` run in CI (via TESTS=1 build.sh)
// without actually running tests on these platforms.
// (Unlike libc, windows-sys programmatically generates bindings from Windows
// API metadata, so it should be enough to check compatibility with the
// windows-sys' signatures/values.)
// See also tools/codegen/src/ffi.rs.
// TODO(codegen): auto-generate this test
#[allow(
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
clippy::cast_possible_truncation,
clippy::no_effect_underscore_binding
)]
const _: fn() = || {
use test_helper::windows_sys;
let _: ffi::DWORD = 0 as windows_sys::Win32::System::Threading::PROCESSOR_FEATURE_ID;
let _: ffi::BOOL = 0 as windows_sys::Win32::Foundation::BOOL;
let mut _sysctl: unsafe extern "system" fn(ffi::DWORD) -> ffi::BOOL =
ffi::IsProcessorFeaturePresent;
_sysctl = windows_sys::Win32::System::Threading::IsProcessorFeaturePresent;
static_assert!(ffi::FALSE == windows_sys::Win32::Foundation::FALSE);
static_assert!(
ffi::PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
== windows_sys::Win32::System::Threading::PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
);
};
}