Tracking Issue for arithmetic and certain bitwise ops on `AtomicPtr`
WaffleLapkin opened this issue · comments
Feature gate: #![feature(strict_provenance_atomic_ptr)]
This is a tracking issue for arithmetic and certain bitwise operations on AtomicPtr
.
As part of the strict provenance experiment #95228.
This feature adds arithmetic (add
, sub
) and bitwise (or
, end
, xor
) atomic operations for AtomicPtr
in order to replace uses of AtomicUsize
-but-actually-a-pointer to preserve provenance information for the compiler and remove usize
->ptr
casts from existing code.
Arithmetic ops behave as the their non-atomic wrapping versions. Bitwise ops behave as .map_addr(|x| x op val)
.
Public API
// core::sync::atomic
impl<T> AtomicPtr<T> {
pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T;
pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T;
pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T;
pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T;
pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T;
pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T;
pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T;
}
Steps / History
Unresolved Questions
- Naming
Footnotes
In terms of implementation details, I think we should also improve the types at which we call the atomic_add
and other core atomic intrinsics. Right now we pass them two pointers and then the backend has to know that the left one is actually a pointer and we care about its provenance, and the right one isn't. Ideally we'd give a pointer as first argument and an integer as second argument.
"The problem" with making rhs usize
is that all atomic intrinsics are currently defined as *mut T -> T -> T
, for example:
rust/library/core/src/intrinsics.rs
Line 111 in 8a392a5
Making the second argument of a different type will probably require compiler changes.
Indeed, and I think those compiler changes should be made. :)
I think ptr
in method names (fetch_ptr_add
and fetch_ptr_sub
) is confusing, we are not adding/subtracting a pointer but instead just add/sub in units of T
. IMO it's too similar to sub_ptr
.
I think the only open question about this API is whether there is a better name for fetch_byte_{add,sub}/fetch_ptr_{add,sub}
(rust-lang/libs-team#126 (comment))? Can we move forward towards stabilization? If those methods are still up for debate, fetch_{or,and,xor}
are pretty straightforward additions (and probably the more common operations) so can probably be stabilized.
Why not just fetch_wrapping_{add, sub}
rather than fetch_ptr_sub
? ptr
in the name seems redundant, and I would expect fetch_add
to be the equivalent of <*const T>::add
(not <*const T>::wrapping_add
)