-
Notifications
You must be signed in to change notification settings - Fork 472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AtomicCell: Use atomic-maybe-uninit #1015
Conversation
16bd406
to
dc12e29
Compare
UPDATE: resolved in Rust 1.74+ by rust-lang/rust#114790 & taiki-e/atomic-maybe-uninit#19. Currently, it is not possible to use MaybeUninit in the input registers of an inline assembly (i.e., when processing MaybeUninit, values must be passed through memory), so this worsens performance. Before:
After (pass by memory):
If I change the atomic-maybe-uninit implementation to pass by value using transmute, performance will be equivalent to the current one, but it is UB when the input value contains uninitialized bytes (because it is transmuted to integer). After (pass by value):
It would be nice if the inline assembly could allow MaybeUninit registers as thomcc had previously proposed. |
Filed rust-lang/rust#114790 to allow MaybeUninit in input and output of inline assembly. |
dc12e29
to
059beeb
Compare
df06c0c
to
f6c99b8
Compare
Allow MaybeUninit in input and output of inline assembly **Motivation:** As part of the work to remove UBs from crossbeam's AtomicCell, I'm writing a library to implement atomic operations on MaybeUnint using inline assembly ([atomic-maybe-uninit](https://github.com/taiki-e/atomic-maybe-uninit), crossbeam-rs/crossbeam#1015). However, currently, MaybeUnint cannot be used in input&output of inline assembly, so when processing MaybeUninit, values must be [passed through memory](https://github.com/taiki-e/atomic-maybe-uninit/blob/main/src/arch/aarch64.rs#L121-L122). It is inefficient and microbenchmarks have [actually shown significant performance degradation](crossbeam-rs/crossbeam#1015 (comment)). It would be nice if we could allow MaybeUninit in input and output of inline assembly. --- This PR changed the type check in rustc_hir_analysis to allow `MaybeUnint<int | float | ptr | fn ptr | simd vector>` in input and output of inline assembly and added a simple test. To be honest, I'm not sure that this is the correct way to do it, because this is like doing transmute to integers/floats/etc from MaybeUninit on the compiler side. EDIT: [this seems fine](https://rust-lang.zulipchat.com/#narrow/stream/216763-project-inline-asm/topic/MaybeUninit.20in.20asm!/near/384662900) r? `@Amanieu` cc `@thomcc` (because you [had previously proposed this](https://rust-lang.zulipchat.com/#narrow/stream/216763-project-inline-asm/topic/MaybeUninit.20in.20asm!))
f6c99b8
to
41732aa
Compare
41732aa
to
1718eec
Compare
76e2b5a
to
a82b2ae
Compare
76b28b7
to
799b84c
Compare
799b84c
to
097154b
Compare
Since this PR was opened we have made many improvements to both atomic-maybe-uninit and the compiler. Resolving performance issue (rust-lang/rust#114790), improving and stabilizing inline assembly support on tier 2 targets (rust-lang/rust#131258, rust-lang/rust#131781, etc.), fixing or avoiding rustc/LLVM bugs, improving code quality (taiki-e/atomic-maybe-uninit#30, etc.), improving platform support (atomic-maybe-uninit currently supports all CPU architectures supported by Rust other than C-SKY), etc. I think we can now finally merge this. |
This fixes UB when lock-free and the value has uninitialized bytes, by using atomic-maybe-uninit crate.
Fixes #315
Fixes #748
Also, this makes 128-bit atomics lock-free on some platforms.
Closes crossbeam-rs/rfcs#13
Currently, this patch always uses fallback (seqlock) on environments that do not support inline assembly, such as Miri.
It is possible to use atomic-maybe-uninit crate to fix UB of concurrent access with volatile read/write in seqlock/deque (#744, #859), but that is not included in this PR and is left to subsequent PRs.
cc @RalfJung