-
Notifications
You must be signed in to change notification settings - Fork 480
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
AtomicU8 is stable (and supported by the MSRV) #744
Comments
This very naive patch passes the tests: - let val = ptr::read_volatile(src);
+ let mut val = std::mem::MaybeUninit::uninit();
+ let mut val_bytes = val.as_mut_ptr() as *mut u8;
+ let mut src_bytes = src as *mut core::sync::atomic::AtomicU8;
+ let src_end = src_bytes.offset(std::mem::size_of::<T>() as isize);
+ let val = unsafe {
+ while src_bytes != src_end {
+ val_bytes.write((*src_bytes).load(Ordering::Relaxed));
+ val_bytes = val_bytes.offset(1);
+ src_bytes = src_bytes.offset(1);
+ }
+ val.assume_init()
+ }; We could try using larger loads like thomcc's tearcell does: https://github.com/thomcc/tearor/blob/c558f6105230a49bb79b8afe989194e7656fdda7/src/lib.rs#L122-L162 instead of a naive byte by byte copy. However, when I asked for review in the community discord server's #dark-arts a problem with padding bytes was mentioned: reading uninit/padding memory with AtomicU8 is not documented to not be UB. No way to fix this without a new language primitive or the language allowing these reads for atomics. For example, for this program use std::mem::MaybeUninit;
use std::sync::atomic::{AtomicU8, Ordering};
fn main() {
#[repr(align(2))]
#[derive(Debug)]
struct WithPadding {
_d: u8,
}
let mut x = WithPadding { _d: 3u8 };
let x_p = std::ptr::addr_of_mut!(x);
let mut y = MaybeUninit::<WithPadding>::uninit();
unsafe {
*y.as_mut_ptr().cast::<u8>() = (*x_p.cast::<AtomicU8>()).load(Ordering::Relaxed);
*y.as_mut_ptr().cast::<u8>().offset(1) =
(*x_p.cast::<AtomicU8>().offset(1)).load(Ordering::Relaxed);
dbg!(y.assume_init());
dbg!(std::mem::size_of::<WithPadding>());
}
} MIRI currently gives the following error (With
|
I have investigated the problem of such before (atomic-memcpy) and there are two main problems with the approach that uses AtomicU8.
For the first problem, p1478r1 has an idea that seems to handle it well, and atomic-memcpy implements a variant of it. (In some cases, it can generate assembly equivalent to volatile read generates. See atomic-memcpy's readme and the implementation comments for more). The second problem actually contains (as far as I know) 2 to 3 problems.
ptr2int2ptr transmute was previously used as a hack to work around ptr2int2ptr cast, but this has recently changed and Miri now reports this case as UB. Even assuming that ptr2int2ptr transmute is not a problem, the approach using AtomicU8 may cause problems with partial copy of pointers. (IIRC, Miri currently reports "unsupported operation: unable to turn pointer into raw bytes" error on this case) The uninitialized byte problem can never be resolved when using std atomic types. Based on the above, I believe that the feature to read and write
I have implemented the third (atomic-maybe-uninit), and I think it needs "audits from someone familiar with these platform-specific codes", "more platform support", and "methods optimized for the case like atomic-memcpy" (inline assembly prevents some optimizations) when use it in crossbeam. EDIT: Of course, using inline assembly in atomic-memcpy or crossbeam is also one of the solutions. Actually, I tried that approach first (taiki-e/atomic-memcpy#6) and then decided to implement it as a separate crate. |
ptr2int2ptr transmute problem could be mostly solved (as long no unaligned pointers are stored in |
Apparently, crossbeam has MSRV
1.36
, which includesAtomicU8
. Hence the following comment is outdated:crossbeam/crossbeam-utils/src/atomic/atomic_cell.rs
Lines 796 to 801 in 2653a6c
Considering that this comment legitimizes code that is officially UB, I propose that this should be fixed, if possible.
The text was updated successfully, but these errors were encountered: