Skip to content

Commit

Permalink
detect: Support run-time detection on AArch64 illumos
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Sep 19, 2024
1 parent 27cdc16 commit 3cc4c94
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 4 deletions.
22 changes: 22 additions & 0 deletions src/imp/atomic128/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ mod detect;
#[path = "../detect/aarch64_aa64reg.rs"]
mod detect;
#[cfg(not(portable_atomic_no_outline_atomics))]
#[cfg(any(test, portable_atomic_outline_atomics))] // TODO(aarch64-illumos): currently disabled by default
#[cfg(any(
test,
not(all(
any(target_feature = "lse2", portable_atomic_target_feature = "lse2"),
any(target_feature = "lse", portable_atomic_target_feature = "lse"),
)),
))]
#[cfg(target_os = "illumos")]
#[path = "../detect/aarch64_illumos.rs"]
mod detect;
#[cfg(not(portable_atomic_no_outline_atomics))]
#[cfg(any(test, not(any(target_feature = "lse", portable_atomic_target_feature = "lse"))))]
#[cfg(target_os = "fuchsia")]
#[path = "../detect/aarch64_fuchsia.rs"]
Expand Down Expand Up @@ -176,6 +188,7 @@ macro_rules! debug_assert_lse {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
target_os = "fuchsia",
target_os = "windows",
),
Expand Down Expand Up @@ -212,6 +225,7 @@ macro_rules! debug_assert_lse2 {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
// These don't support detection of FEAT_LSE2.
// target_os = "fuchsia",
// target_os = "windows",
Expand Down Expand Up @@ -252,6 +266,7 @@ macro_rules! debug_assert_lse128 {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
// These don't support detection of FEAT_LSE128.
// target_os = "fuchsia",
// target_os = "windows",
Expand Down Expand Up @@ -292,6 +307,7 @@ macro_rules! debug_assert_rcpc3 {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
// These don't support detection of FEAT_LRCPC3.
// target_os = "fuchsia",
// target_os = "windows",
Expand Down Expand Up @@ -504,6 +520,7 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
// These don't support detection of FEAT_LSE2.
// target_os = "fuchsia",
// target_os = "windows",
Expand Down Expand Up @@ -600,6 +617,7 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
// These don't support detection of FEAT_LSE2.
// target_os = "fuchsia",
// target_os = "windows",
Expand Down Expand Up @@ -925,6 +943,7 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
// These don't support detection of FEAT_LSE2.
// target_os = "fuchsia",
// target_os = "windows",
Expand Down Expand Up @@ -1029,6 +1048,7 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
// These don't support detection of FEAT_LSE2.
// target_os = "fuchsia",
// target_os = "windows",
Expand Down Expand Up @@ -1254,6 +1274,7 @@ unsafe fn atomic_compare_exchange(
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
target_os = "fuchsia",
target_os = "windows",
),
Expand Down Expand Up @@ -1392,6 +1413,7 @@ unsafe fn atomic_compare_exchange(
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
all(target_os = "illumos", portable_atomic_outline_atomics),
target_os = "fuchsia",
target_os = "windows",
),
Expand Down
1 change: 1 addition & 0 deletions src/imp/detect/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Here is the table of targets that support run-time CPU feature detection and the
| aarch64 | netbsd | sysctlbyname | all | Enabled by default |
| aarch64 | openbsd | sysctl | all | Enabled by default |
| aarch64 | macos/ios/tvos/watchos/visionos | sysctlbyname | all | Currently only used in tests (see [aarch64_apple.rs](aarch64_apple.rs)). |
| aarch64 | illumos | getisax | lse, lse2 | Disabled by default |
| aarch64 | windows | IsProcessorFeaturePresent | lse | Enabled by default |
| aarch64 | fuchsia | zx_system_get_features | lse | Enabled by default |
| riscv32 | linux | riscv_hwprobe | all | Currently only used in tests due to LLVM marking zacas as experimental |
Expand Down
82 changes: 82 additions & 0 deletions src/imp/detect/aarch64_illumos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

/*
Run-time CPU feature detection on AArch64 illumos by using getisax.
As of nightly-2024-09-07, is_aarch64_feature_detected doesn't support run-time detection on illumos.
https://github.com/rust-lang/stdarch/blob/d9466edb4c53cece8686ee6e17b028436ddf4151/crates/std_detect/src/detect/mod.rs
Run-time detection on AArch64 illumos is currently disabled by default as AArch64 port is experimental.
*/

include!("common.rs");

// core::ffi::c_* (except c_void) requires Rust 1.64, libc will soon require Rust 1.47
#[allow(non_camel_case_types)]
mod ffi {
pub(crate) use super::c_types::c_uint;

// Defined in sys/auxv_aarch64.h.
// https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv_aarch64.h
pub(crate) const AV_AARCH64_LSE: u32 = 1 << 15;
pub(crate) const AV_AARCH64_2_LSE2: u32 = 1 << 2;

extern "C" {
// Defined in sys/auxv.h.
// https://illumos.org/man/2/getisax
// https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv.h
pub(crate) fn getisax(array: *mut u32, n: c_uint) -> c_uint;
}
}

#[cold]
fn _detect(info: &mut CpuInfo) {
let mut out = [0_u32; 2];
// SAFETY: the pointer is valid because we got it from a reference.
unsafe {
ffi::getisax(out.as_mut_ptr(), 2);
}
if out[0] & ffi::AV_AARCH64_LSE != 0 {
info.set(CpuInfo::HAS_LSE);
}
if out[1] & ffi::AV_AARCH64_2_LSE2 != 0 {
info.set(CpuInfo::HAS_LSE2);
}
}

#[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
// generated for the platform's latest header file using bindgen 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.
// 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::sys;
let mut _getisax: unsafe extern "C" fn(*mut u32, ffi::c_uint) -> ffi::c_uint = ffi::getisax;
_getisax = sys::getisax;
// static_assert!(ffi::AV_AARCH64_LSE == libc::AV_AARCH64_LSE);
static_assert!(ffi::AV_AARCH64_LSE == sys::AV_AARCH64_LSE);
// static_assert!(ffi::AV_AARCH64_2_LSE2 == libc::AV_AARCH64_2_LSE2);
static_assert!(ffi::AV_AARCH64_2_LSE2 == sys::AV_AARCH64_2_LSE2);
};
}
5 changes: 3 additions & 2 deletions src/imp/detect/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,10 @@ mod c_types {
let _: c_long = 0 as std::os::raw::c_long;
let _: c_ulong = 0 as std::os::raw::c_ulong;
let _: c_size_t = 0 as libc::size_t; // std::os::raw::c_size_t is unstable
#[cfg(not(
#[cfg(not(any(
all(target_arch = "aarch64", target_os = "illumos"), // TODO: https://github.com/rust-lang/rust/issues/129945
all(target_arch = "riscv64", target_os = "android"), // TODO: https://github.com/rust-lang/rust/issues/129945
))]
)))]
let _: c_char = 0 as std::os::raw::c_char;
let _: c_char = 0 as sys::c_char;
};
Expand Down
5 changes: 3 additions & 2 deletions tools/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ default_targets=(
aarch64-unknown-linux-uclibc # custom target
aarch64-unknown-netbsd
aarch64-unknown-openbsd
aarch64-unknown-illumos
# FEAT_LSE & FEAT_LSE2
aarch64-apple-darwin
# big endian
Expand Down Expand Up @@ -511,9 +512,9 @@ build() {
;;
esac
case "${target}" in
# portable_atomic_outline_atomics only affects aarch64 Linux and powerpc64.
# portable_atomic_outline_atomics only affects aarch64 Linux/illumos and powerpc64.
# powerpc64le- (little-endian) is skipped because it is pwr8 by default
aarch64*-linux-* | powerpc64-*)
aarch64*-linux-* | aarch64*-illumos* | powerpc64-*)
CARGO_TARGET_DIR="${target_dir}/outline-atomics" \
RUSTFLAGS="${target_rustflags} --cfg portable_atomic_outline_atomics" \
x_cargo "${args[@]}" "$@"
Expand Down

0 comments on commit 3cc4c94

Please sign in to comment.