You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It'd be useful to be able to perform atomic operations on parts of atomic integer in addition to the whole thing.
e.g. the following runs as expected, including under miri:
use std::sync::atomic;
pub fn main() {
let whole: atomic::AtomicU64 = atomic::AtomicU64::new(0);
// Valid because AtomicU64 is repr(transparent) around a u64,
// and likewise AtomicU32 for u32.
let parts_ptr = &whole as *const _ as *const atomic::AtomicU32;
// We can create valid references for the "top"
// and "bottom" parts of the Atomicu64.
let top: &atomic::AtomicU32 = unsafe { &*parts_ptr };
let bottom: &atomic::AtomicU32 = unsafe { &*parts_ptr.add(1) };
// And we can operate on them.
top.fetch_add(1, atomic::Ordering::Relaxed);
bottom.fetch_add(1, atomic::Ordering::Relaxed);
// We can still operate on the whole word.
assert_eq!(whole.load(atomic::Ordering::Relaxed), 1u64 + (1u64 << 32));
}
This isn't valid using loom's atomics, since they aren't repr(transparent) wrappers around the underlying integer types.
Is there some way that miri atomics might be able to support this?
As a motivating example, I'm implementing a mutex, and would like to be keep the locked/unlocked state, and the number of threads sleeping on the mutex, in a 64 bit integer, in the individual 32 bit pieces. I'd like to be able to e.g. compare and swap the mutex state without caring about the number of sleepers when locking, while still being able to atomically unlock and get the sleeper count when unlocking.
The text was updated successfully, but these errors were encountered:
In fact, when I run your example in multi-threaded, Miri reports an error that the operation is not supported.
error: unsupported operation: racy imperfectly overlapping atomic access is not possible in the C++20 memory model, and not supported by Miri's weak memory emulation
--> src/main.rs:16:9
|
16 | top.fetch_add(1, atomic::Ordering::Relaxed);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ racy imperfectly overlapping atomic access is not possible in the C++20 memory model, and not supported by Miri's weak memory emulation
|
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
= note: BACKTRACE:
= note: inside closure at src/main.rs:16:9
Thanks for the reference and counterexample! Looks like loom steered me in the right direction here, at least while it's still an open issue in Rust itself.
Yeah, the only reason your original code works is that they don't happen in parallel. I don't think we are going to support this unless std defines the behavior.
It'd be useful to be able to perform atomic operations on parts of atomic integer in addition to the whole thing.
e.g. the following runs as expected, including under miri:
This isn't valid using loom's atomics, since they aren't
repr(transparent)
wrappers around the underlying integer types.Is there some way that miri atomics might be able to support this?
As a motivating example, I'm implementing a mutex, and would like to be keep the locked/unlocked state, and the number of threads sleeping on the mutex, in a 64 bit integer, in the individual 32 bit pieces. I'd like to be able to e.g. compare and swap the mutex state without caring about the number of sleepers when locking, while still being able to atomically unlock and get the sleeper count when unlocking.
The text was updated successfully, but these errors were encountered: