• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 OR MIT
2 
3 /*
4 Run-time CPU feature detection on AArch64 Windows by using IsProcessorFeaturePresent.
5 
6 Run-time detection of FEAT_LSE on Windows by is_aarch64_feature_detected is supported on Rust 1.70+.
7 https://github.com/rust-lang/stdarch/pull/1373
8 
9 Refs: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
10 */
11 
12 include!("common.rs");
13 
14 // windows-sys requires Rust 1.60
15 #[allow(clippy::upper_case_acronyms)]
16 mod ffi {
17     pub(crate) type DWORD = u32;
18     pub(crate) type BOOL = i32;
19 
20     pub(crate) const FALSE: BOOL = 0;
21 
22     // Defined in winnt.h of Windows SDK.
23     pub(crate) const PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE: DWORD = 34;
24 
25     extern "system" {
26         // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
IsProcessorFeaturePresent(ProcessorFeature: DWORD) -> BOOL27         pub(crate) fn IsProcessorFeaturePresent(ProcessorFeature: DWORD) -> BOOL;
28     }
29 }
30 
31 #[cold]
_detect(info: &mut CpuInfo)32 fn _detect(info: &mut CpuInfo) {
33     // SAFETY: calling IsProcessorFeaturePresent is safe, and FALSE is also
34     // returned if the HAL does not support detection of the specified feature.
35     if unsafe {
36         ffi::IsProcessorFeaturePresent(ffi::PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE) != ffi::FALSE
37     } {
38         info.set(CpuInfo::HAS_LSE);
39     }
40 }
41 
42 #[allow(
43     clippy::alloc_instead_of_core,
44     clippy::std_instead_of_alloc,
45     clippy::std_instead_of_core,
46     clippy::undocumented_unsafe_blocks,
47     clippy::wildcard_imports
48 )]
49 #[cfg(test)]
50 mod tests {
51     use super::*;
52 
53     // Static assertions for FFI bindings.
54     // This checks that FFI bindings defined in this crate and FFI bindings defined
55     // in windows-sys have compatible signatures (or the same values if constants).
56     // Since this is static assertion, we can detect problems with
57     // `cargo check --tests --target <target>` run in CI (via TESTS=1 build.sh)
58     // without actually running tests on these platforms.
59     // (Unlike libc, windows-sys programmatically generates bindings from Windows
60     // API metadata, so it should be enough to check compatibility with the
61     // windows-sys' signatures/values.)
62     // See also tools/codegen/src/ffi.rs.
63     // TODO(codegen): auto-generate this test
64     #[allow(
65         clippy::cast_possible_wrap,
66         clippy::cast_sign_loss,
67         clippy::cast_possible_truncation,
68         clippy::no_effect_underscore_binding
69     )]
70     const _: fn() = || {
71         use test_helper::windows_sys;
72         let _: ffi::DWORD = 0 as windows_sys::Win32::System::Threading::PROCESSOR_FEATURE_ID;
73         let _: ffi::BOOL = 0 as windows_sys::Win32::Foundation::BOOL;
74         let mut _is_processor_feature_present: unsafe extern "system" fn(ffi::DWORD) -> ffi::BOOL =
75             ffi::IsProcessorFeaturePresent;
76         _is_processor_feature_present =
77             windows_sys::Win32::System::Threading::IsProcessorFeaturePresent;
78         static_assert!(ffi::FALSE == windows_sys::Win32::Foundation::FALSE);
79         static_assert!(
80             ffi::PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
81                 == windows_sys::Win32::System::Threading::PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
82         );
83     };
84 }
85