Auto merge of #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, #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].
This commit is contained in:
commit
f47f53c9f4
@ -27,8 +27,12 @@ pub fn target() -> TargetResult {
|
||||
|
||||
options: TargetOptions {
|
||||
features: "+soft-float,+strict-align".to_string(),
|
||||
// No atomic instructions on ARMv5
|
||||
max_atomic_width: Some(0),
|
||||
|
||||
// Atomic operations provided when linked with libgcc.
|
||||
// FIXME: If the following PR is merged, the atomic operations would be
|
||||
// provided by compiler-builtins instead with no change of behavior:
|
||||
// https://github.com/rust-lang-nursery/compiler-builtins/pull/115/files
|
||||
max_atomic_width: Some(32),
|
||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||
.. base
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user