Conversation
a7a39ac to
b91c04c
Compare
aecb2af to
97993ae
Compare
Owner
Author
|
Ok, benchmarked on Graviton2 (Neoverse-N1)'s aarch32 mode. https://cirrus-ci.com/task/6137907514179584 |
tgross35
pushed a commit
to rust-lang/compiler-builtins
that referenced
this pull request
Jan 22, 2026
This is a PR for thumbv6-none-eabi (bere-metal Armv6k in Thumb mode) which proposed to be added by rust-lang/rust#150138. Armv6k supports atomic instructions, but they are unavailable in Thumb mode unless Thumb-2 instructions available (v6t2). Using Thumb interworking (can be used via `#[instruction_set]`) allows us to use these instructions even from Thumb mode without Thumb-2 instructions, but LLVM does not implement that processing (as of LLVM 21), so this PR implements it in compiler-builtins. The code around `__sync` builtins is basically copied from `arm_linux.rs` which uses kernel_user_helpers for atomic implementation. The atomic implementation is a port of my [atomic-maybe-uninit inline assembly code]. This PR has been tested on QEMU 10.2.0 using patched compiler-builtins and core that applied the changes in this PR and rust-lang/rust#150138 and the [portable-atomic no-std test suite] (can be run with `./tools/no-std.sh thumbv6-none-eabi` on that repo) which tests wrappers around `core::sync::atomic`. (Note that the target-spec used in test sets max-atomic-width to 32 and atomic_cas to true, unlike the current rust-lang/rust#150138.) The original atomic-maybe-uninit implementation has been tested on real Arm hardware. (Note that Armv6k also supports 64-bit atomic instructions, but they are skipped here. This is because there is no corresponding code in `arm_linux.rs` (since the kernel requirements increased in 1.64, it may be possible to implement 64-bit atomics there as well. see also taiki-e/portable-atomic#82), the code becomes more complex than for 32-bit and smaller atomics.) [atomic-maybe-uninit inline assembly code]: https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/arm.rs [portable-atomic no-std test suite]: https://github.com/taiki-e/portable-atomic/tree/HEAD/tests/no-std-qemu
tgross35
pushed a commit
to tgross35/rust
that referenced
this pull request
Feb 10, 2026
This is a PR for thumbv6-none-eabi (bere-metal Armv6k in Thumb mode) which proposed to be added by rust-lang#150138. Armv6k supports atomic instructions, but they are unavailable in Thumb mode unless Thumb-2 instructions available (v6t2). Using Thumb interworking (can be used via `#[instruction_set]`) allows us to use these instructions even from Thumb mode without Thumb-2 instructions, but LLVM does not implement that processing (as of LLVM 21), so this PR implements it in compiler-builtins. The code around `__sync` builtins is basically copied from `arm_linux.rs` which uses kernel_user_helpers for atomic implementation. The atomic implementation is a port of my [atomic-maybe-uninit inline assembly code]. This PR has been tested on QEMU 10.2.0 using patched compiler-builtins and core that applied the changes in this PR and rust-lang#150138 and the [portable-atomic no-std test suite] (can be run with `./tools/no-std.sh thumbv6-none-eabi` on that repo) which tests wrappers around `core::sync::atomic`. (Note that the target-spec used in test sets max-atomic-width to 32 and atomic_cas to true, unlike the current rust-lang#150138.) The original atomic-maybe-uninit implementation has been tested on real Arm hardware. (Note that Armv6k also supports 64-bit atomic instructions, but they are skipped here. This is because there is no corresponding code in `arm_linux.rs` (since the kernel requirements increased in 1.64, it may be possible to implement 64-bit atomics there as well. see also taiki-e/portable-atomic#82), the code becomes more complex than for 32-bit and smaller atomics.) [atomic-maybe-uninit inline assembly code]: https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/arm.rs [portable-atomic no-std test suite]: https://github.com/taiki-e/portable-atomic/tree/HEAD/tests/no-std-qemu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Currently, we are using fallback implementation for 64-bit atomics on pre-v6 ARM Linux/Android such as armv5te-unknown-linux-gnueabi and arm-linux-androideabi.
However, Linux kernel 3.1+ provides kernel user helpers for 64-bit atomics. This could be more efficient than a lock-based fallback implementation, because it calls native atomic instructions, depending on the actual CPU version.
This PR uses __kuser_cmpxchg64 on Linux kernel 3.1+, otherwise use fallback implementation as before.
Since Rust 1.64, the Linux kernel requirement for Rust when using std1 is 3.2+, so it should be possible to omit the dynamic kernel version check if the std feature is enabled on Rust 1.64+, but that has not yet been implemented.
Footnotes
https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html#affected-targets says "Targets which only use libcore and not libstd are unaffected." ↩