Skip to content

Commit 12b5e55

Browse files
committed
Move aarch64 outline-atomic initialization to sys::arch
Create a private module to hold the bootstrap code needed enable LSE at startup on aarch64-*-linux-gnu* targets when rust implements the intrinsics. This is a bit more heavyweight than compiler-rt's LSE initialization, but has the benefit of initializing the aarch64 cpu feature detection for other uses. Using the rust initialization code does use some atomic operations, that's OK. Mixing LSE and non-LSE operations should work while the update flag propagates.
1 parent 3dd96a4 commit 12b5e55

File tree

3 files changed

+31
-25
lines changed

3 files changed

+31
-25
lines changed

library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,33 +24,12 @@
2424
use core::sync::atomic::{AtomicU8, Ordering};
2525

2626
/// non-zero if the host supports LSE atomics.
27-
#[cfg(not(feature = "c"))]
2827
static HAVE_LSE_ATOMICS: AtomicU8 = AtomicU8::new(0);
2928

30-
/// outline-atomics are only enabled with glibc support, add a .init_array entry to
31-
/// check and enable LSE via getauxval. This behavior is similar to compiler rt.
32-
#[cfg(target_env = "gnu")]
33-
#[unsafe(link_section = ".init_array.90")]
34-
pub static RUST_LSE_INIT: extern "C" fn() = {
35-
extern "C" fn aarch64_rust_init_lse_atomics() {
36-
const AT_HWCAP: core::ffi::c_ulong = 16;
37-
const HWCAP_ATOMICS: core::ffi::c_ulong = 0x100;
38-
let hwcap;
39-
40-
// The most straightforward path to querying for LSE support is the host's libc.
41-
// We can't use the libc crate here, we are a dependency.
42-
unsafe extern "C" {
43-
fn getauxval(num: core::ffi::c_ulong) -> core::ffi::c_ulong;
44-
}
45-
unsafe {
46-
hwcap = getauxval(AT_HWCAP);
47-
}
48-
if hwcap & HWCAP_ATOMICS != 0 {
49-
HAVE_LSE_ATOMICS.store(1, Ordering::Relaxed);
50-
}
51-
}
52-
aarch64_rust_init_lse_atomics
53-
};
29+
/// Call to enable LSE atomic operations.
30+
pub fn enable_lse() {
31+
HAVE_LSE_ATOMICS.store(1, Ordering::Relaxed);
32+
}
5433

5534
/// Translate a byte size to a Rust type.
5635
#[rustfmt::skip]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/// Hook into .init_array to enable LSE atomic operations at startup, if
2+
/// supported. outline-atomics is only enabled on aarch64-*-gnu* targets,
3+
/// initialization is limited to those targets.
4+
#[cfg(all(
5+
target_arch = "aarch64",
6+
target_os = "linux",
7+
target_env = "gnu",
8+
not(feature = "compiler-builtins-c")
9+
))]
10+
#[used]
11+
#[unsafe(link_section = ".init_array.90")]
12+
static RUST_LSE_INIT: extern "C" fn() = {
13+
extern "C" fn init_lse() {
14+
use compiler_builtins::aarch64_linux;
15+
16+
use crate::arch;
17+
if arch::is_aarch64_feature_detected!("lse") {
18+
aarch64_linux::enable_lse();
19+
}
20+
}
21+
init_lse
22+
};

library/std/src/sys/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#![allow(unsafe_op_in_unsafe_fn)]
22

3+
/// The configure builtins provides runtime support compiler-builtin features
4+
/// which require dynamic intialization to work as expected, e.g. aarch64
5+
/// outline-atomics.
6+
mod configure_builtins;
7+
38
/// The PAL (platform abstraction layer) contains platform-specific abstractions
49
/// for implementing the features in the other submodules, e.g. UNIX file
510
/// descriptors.

0 commit comments

Comments
 (0)