Skip to content

Commit f47f53c

Browse files
committed
Auto merge of rust-lang#44978 - jamesmunns:armv5te-os-atomics, r=alexcrichton
Allow atomic operations up to 32 bits The ARMv5te platform does not have instruction-level support for atomics, however the kernel provides [user space helpers] which can be used to perform atomic operations. When linked with `libgcc`, the atomic symbols needed by Rust will be provided, rather than CPU level intrinsics. [user space helpers]: https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt 32-bit versions of these kernel level helpers were introduced in Linux Kernel 2.6.12, and 64-bit version of these kernel level helpers were introduced in Linux Kernel 3.1. I have selected 32 bit versions as std currently only requires Linux version 2.6.18 and above as far as I am aware. As this target is specifically linux and gnueabi, it is reasonable to assume the Linux Kernel and libc will be available for the target. There is a large performance penalty, as we are not using CPU level intrinsics, however this penalty is likely preferable to not having the target at all. I have used this change in a custom target (along with xargo) to build std, as well as a number of higher level crates. ## Additional information For reference, here is what a a code snippet decompiles to: ```rust use std::sync::atomic::{AtomicIsize, Ordering}; #[no_mangle] pub extern fn foo(a: &AtomicIsize) -> isize { a.fetch_add(1, Ordering::SeqCst) } ``` ``` Disassembly of section .text.foo: 00000000 <foo>: 0: e92d4800 push {fp, lr} 4: e3a01001 mov r1, #1 8: ebfffffe bl 0 <__sync_fetch_and_add_4> c: e8bd8800 pop {fp, pc} ``` Which in turn is provided by `libgcc.a`, which has code which looks like this: ``` Disassembly of section .text: 00000000 <__sync_fetch_and_add_4>: 0: e92d40f8 push {r3, r4, r5, r6, r7, lr} 4: e1a05000 mov r5, r0 8: e1a07001 mov r7, r1 c: e59f6028 ldr r6, [pc, rust-lang#40] ; 3c <__sync_fetch_and_add_4+0x3c> 10: e5954000 ldr r4, [r5] 14: e1a02005 mov r2, r5 18: e1a00004 mov r0, r4 1c: e0841007 add r1, r4, r7 20: e1a0e00f mov lr, pc 24: e12fff16 bx r6 28: e3500000 cmp r0, #0 2c: 1afffff7 bne 10 <__sync_fetch_and_add_4+0x10> 30: e1a00004 mov r0, r4 34: e8bd40f8 pop {r3, r4, r5, r6, r7, lr} 38: e12fff1e bx lr 3c: ffff0fc0 .word 0xffff0fc0 ``` Where you can see the reference to `0xffff0fc0`, which is provided by the [user space helpers].
2 parents ac76206 + 1e26094 commit f47f53c

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ pub fn target() -> TargetResult {
2727

2828
options: TargetOptions {
2929
features: "+soft-float,+strict-align".to_string(),
30-
// No atomic instructions on ARMv5
31-
max_atomic_width: Some(0),
30+
31+
// Atomic operations provided when linked with libgcc.
32+
// FIXME: If the following PR is merged, the atomic operations would be
33+
// provided by compiler-builtins instead with no change of behavior:
34+
// https://github.com/rust-lang-nursery/compiler-builtins/pull/115/files
35+
max_atomic_width: Some(32),
3236
abi_blacklist: super::arm_base::abi_blacklist(),
3337
.. base
3438
}

0 commit comments

Comments
 (0)