Commit f47f53c
committed
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].1 file changed
+6
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
31 | | - | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
32 | 36 | | |
33 | 37 | | |
34 | 38 | | |
| |||
0 commit comments