Skip to content

Commit 33057d9

Browse files
committed
atomicrmw on pointers: move integer-pointer cast hacks into backend
1 parent 16f86fa commit 33057d9

File tree

2 files changed

+57
-62
lines changed

2 files changed

+57
-62
lines changed

core/src/intrinsics/mod.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -150,69 +150,63 @@ pub unsafe fn atomic_xchg<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src:
150150

151151
/// Adds to the current value, returning the previous value.
152152
/// `T` must be an integer or pointer type.
153-
/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
154-
/// value stored at `*dst` will have the provenance of the old value stored there.
153+
/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
155154
///
156155
/// The stabilized version of this intrinsic is available on the
157156
/// [`atomic`] types via the `fetch_add` method. For example, [`AtomicIsize::fetch_add`].
158157
#[rustc_intrinsic]
159158
#[rustc_nounwind]
160-
pub unsafe fn atomic_xadd<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
159+
pub unsafe fn atomic_xadd<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
161160

162161
/// Subtract from the current value, returning the previous value.
163162
/// `T` must be an integer or pointer type.
164-
/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
165-
/// value stored at `*dst` will have the provenance of the old value stored there.
163+
/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
166164
///
167165
/// The stabilized version of this intrinsic is available on the
168166
/// [`atomic`] types via the `fetch_sub` method. For example, [`AtomicIsize::fetch_sub`].
169167
#[rustc_intrinsic]
170168
#[rustc_nounwind]
171-
pub unsafe fn atomic_xsub<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
169+
pub unsafe fn atomic_xsub<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
172170

173171
/// Bitwise and with the current value, returning the previous value.
174172
/// `T` must be an integer or pointer type.
175-
/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
176-
/// value stored at `*dst` will have the provenance of the old value stored there.
173+
/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
177174
///
178175
/// The stabilized version of this intrinsic is available on the
179176
/// [`atomic`] types via the `fetch_and` method. For example, [`AtomicBool::fetch_and`].
180177
#[rustc_intrinsic]
181178
#[rustc_nounwind]
182-
pub unsafe fn atomic_and<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
179+
pub unsafe fn atomic_and<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
183180

184181
/// Bitwise nand with the current value, returning the previous value.
185182
/// `T` must be an integer or pointer type.
186-
/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
187-
/// value stored at `*dst` will have the provenance of the old value stored there.
183+
/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
188184
///
189185
/// The stabilized version of this intrinsic is available on the
190186
/// [`AtomicBool`] type via the `fetch_nand` method. For example, [`AtomicBool::fetch_nand`].
191187
#[rustc_intrinsic]
192188
#[rustc_nounwind]
193-
pub unsafe fn atomic_nand<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
189+
pub unsafe fn atomic_nand<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
194190

195191
/// Bitwise or with the current value, returning the previous value.
196192
/// `T` must be an integer or pointer type.
197-
/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
198-
/// value stored at `*dst` will have the provenance of the old value stored there.
193+
/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
199194
///
200195
/// The stabilized version of this intrinsic is available on the
201196
/// [`atomic`] types via the `fetch_or` method. For example, [`AtomicBool::fetch_or`].
202197
#[rustc_intrinsic]
203198
#[rustc_nounwind]
204-
pub unsafe fn atomic_or<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
199+
pub unsafe fn atomic_or<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
205200

206201
/// Bitwise xor with the current value, returning the previous value.
207202
/// `T` must be an integer or pointer type.
208-
/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
209-
/// value stored at `*dst` will have the provenance of the old value stored there.
203+
/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
210204
///
211205
/// The stabilized version of this intrinsic is available on the
212206
/// [`atomic`] types via the `fetch_xor` method. For example, [`AtomicBool::fetch_xor`].
213207
#[rustc_intrinsic]
214208
#[rustc_nounwind]
215-
pub unsafe fn atomic_xor<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
209+
pub unsafe fn atomic_xor<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
216210

217211
/// Maximum with the current value using a signed comparison.
218212
/// `T` must be a signed integer type.

core/src/sync/atomic.rs

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,7 +2291,7 @@ impl<T> AtomicPtr<T> {
22912291
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
22922292
pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
22932293
// SAFETY: data races are prevented by atomic intrinsics.
2294-
unsafe { atomic_add(self.p.get(), core::ptr::without_provenance_mut(val), order).cast() }
2294+
unsafe { atomic_add(self.p.get(), val, order).cast() }
22952295
}
22962296

22972297
/// Offsets the pointer's address by subtracting `val` *bytes*, returning the
@@ -2316,17 +2316,18 @@ impl<T> AtomicPtr<T> {
23162316
/// #![feature(strict_provenance_atomic_ptr)]
23172317
/// use core::sync::atomic::{AtomicPtr, Ordering};
23182318
///
2319-
/// let atom = AtomicPtr::<i64>::new(core::ptr::without_provenance_mut(1));
2320-
/// assert_eq!(atom.fetch_byte_sub(1, Ordering::Relaxed).addr(), 1);
2321-
/// assert_eq!(atom.load(Ordering::Relaxed).addr(), 0);
2319+
/// let mut arr = [0i64, 1];
2320+
/// let atom = AtomicPtr::<i64>::new(&raw mut arr[1]);
2321+
/// assert_eq!(atom.fetch_byte_sub(8, Ordering::Relaxed).addr(), (&raw const arr[1]).addr());
2322+
/// assert_eq!(atom.load(Ordering::Relaxed).addr(), (&raw const arr[0]).addr());
23222323
/// ```
23232324
#[inline]
23242325
#[cfg(target_has_atomic = "ptr")]
23252326
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
23262327
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
23272328
pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
23282329
// SAFETY: data races are prevented by atomic intrinsics.
2329-
unsafe { atomic_sub(self.p.get(), core::ptr::without_provenance_mut(val), order).cast() }
2330+
unsafe { atomic_sub(self.p.get(), val, order).cast() }
23302331
}
23312332

23322333
/// Performs a bitwise "or" operation on the address of the current pointer,
@@ -2377,7 +2378,7 @@ impl<T> AtomicPtr<T> {
23772378
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
23782379
pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
23792380
// SAFETY: data races are prevented by atomic intrinsics.
2380-
unsafe { atomic_or(self.p.get(), core::ptr::without_provenance_mut(val), order).cast() }
2381+
unsafe { atomic_or(self.p.get(), val, order).cast() }
23812382
}
23822383

23832384
/// Performs a bitwise "and" operation on the address of the current
@@ -2427,7 +2428,7 @@ impl<T> AtomicPtr<T> {
24272428
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
24282429
pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
24292430
// SAFETY: data races are prevented by atomic intrinsics.
2430-
unsafe { atomic_and(self.p.get(), core::ptr::without_provenance_mut(val), order).cast() }
2431+
unsafe { atomic_and(self.p.get(), val, order).cast() }
24312432
}
24322433

24332434
/// Performs a bitwise "xor" operation on the address of the current
@@ -2475,7 +2476,7 @@ impl<T> AtomicPtr<T> {
24752476
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
24762477
pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
24772478
// SAFETY: data races are prevented by atomic intrinsics.
2478-
unsafe { atomic_xor(self.p.get(), core::ptr::without_provenance_mut(val), order).cast() }
2479+
unsafe { atomic_xor(self.p.get(), val, order).cast() }
24792480
}
24802481

24812482
/// Returns a mutable pointer to the underlying pointer.
@@ -3975,15 +3976,15 @@ unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
39753976
#[inline]
39763977
#[cfg(target_has_atomic)]
39773978
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3978-
unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3979+
unsafe fn atomic_add<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
39793980
// SAFETY: the caller must uphold the safety contract for `atomic_add`.
39803981
unsafe {
39813982
match order {
3982-
Relaxed => intrinsics::atomic_xadd::<T, { AO::Relaxed }>(dst, val),
3983-
Acquire => intrinsics::atomic_xadd::<T, { AO::Acquire }>(dst, val),
3984-
Release => intrinsics::atomic_xadd::<T, { AO::Release }>(dst, val),
3985-
AcqRel => intrinsics::atomic_xadd::<T, { AO::AcqRel }>(dst, val),
3986-
SeqCst => intrinsics::atomic_xadd::<T, { AO::SeqCst }>(dst, val),
3983+
Relaxed => intrinsics::atomic_xadd::<T, U, { AO::Relaxed }>(dst, val),
3984+
Acquire => intrinsics::atomic_xadd::<T, U, { AO::Acquire }>(dst, val),
3985+
Release => intrinsics::atomic_xadd::<T, U, { AO::Release }>(dst, val),
3986+
AcqRel => intrinsics::atomic_xadd::<T, U, { AO::AcqRel }>(dst, val),
3987+
SeqCst => intrinsics::atomic_xadd::<T, U, { AO::SeqCst }>(dst, val),
39873988
}
39883989
}
39893990
}
@@ -3992,15 +3993,15 @@ unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
39923993
#[inline]
39933994
#[cfg(target_has_atomic)]
39943995
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3995-
unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3996+
unsafe fn atomic_sub<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
39963997
// SAFETY: the caller must uphold the safety contract for `atomic_sub`.
39973998
unsafe {
39983999
match order {
3999-
Relaxed => intrinsics::atomic_xsub::<T, { AO::Relaxed }>(dst, val),
4000-
Acquire => intrinsics::atomic_xsub::<T, { AO::Acquire }>(dst, val),
4001-
Release => intrinsics::atomic_xsub::<T, { AO::Release }>(dst, val),
4002-
AcqRel => intrinsics::atomic_xsub::<T, { AO::AcqRel }>(dst, val),
4003-
SeqCst => intrinsics::atomic_xsub::<T, { AO::SeqCst }>(dst, val),
4000+
Relaxed => intrinsics::atomic_xsub::<T, U, { AO::Relaxed }>(dst, val),
4001+
Acquire => intrinsics::atomic_xsub::<T, U, { AO::Acquire }>(dst, val),
4002+
Release => intrinsics::atomic_xsub::<T, U, { AO::Release }>(dst, val),
4003+
AcqRel => intrinsics::atomic_xsub::<T, U, { AO::AcqRel }>(dst, val),
4004+
SeqCst => intrinsics::atomic_xsub::<T, U, { AO::SeqCst }>(dst, val),
40044005
}
40054006
}
40064007
}
@@ -4141,63 +4142,63 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
41414142
#[inline]
41424143
#[cfg(target_has_atomic)]
41434144
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4144-
unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4145+
unsafe fn atomic_and<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
41454146
// SAFETY: the caller must uphold the safety contract for `atomic_and`
41464147
unsafe {
41474148
match order {
4148-
Relaxed => intrinsics::atomic_and::<T, { AO::Relaxed }>(dst, val),
4149-
Acquire => intrinsics::atomic_and::<T, { AO::Acquire }>(dst, val),
4150-
Release => intrinsics::atomic_and::<T, { AO::Release }>(dst, val),
4151-
AcqRel => intrinsics::atomic_and::<T, { AO::AcqRel }>(dst, val),
4152-
SeqCst => intrinsics::atomic_and::<T, { AO::SeqCst }>(dst, val),
4149+
Relaxed => intrinsics::atomic_and::<T, U, { AO::Relaxed }>(dst, val),
4150+
Acquire => intrinsics::atomic_and::<T, U, { AO::Acquire }>(dst, val),
4151+
Release => intrinsics::atomic_and::<T, U, { AO::Release }>(dst, val),
4152+
AcqRel => intrinsics::atomic_and::<T, U, { AO::AcqRel }>(dst, val),
4153+
SeqCst => intrinsics::atomic_and::<T, U, { AO::SeqCst }>(dst, val),
41534154
}
41544155
}
41554156
}
41564157

41574158
#[inline]
41584159
#[cfg(target_has_atomic)]
41594160
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4160-
unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4161+
unsafe fn atomic_nand<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
41614162
// SAFETY: the caller must uphold the safety contract for `atomic_nand`
41624163
unsafe {
41634164
match order {
4164-
Relaxed => intrinsics::atomic_nand::<T, { AO::Relaxed }>(dst, val),
4165-
Acquire => intrinsics::atomic_nand::<T, { AO::Acquire }>(dst, val),
4166-
Release => intrinsics::atomic_nand::<T, { AO::Release }>(dst, val),
4167-
AcqRel => intrinsics::atomic_nand::<T, { AO::AcqRel }>(dst, val),
4168-
SeqCst => intrinsics::atomic_nand::<T, { AO::SeqCst }>(dst, val),
4165+
Relaxed => intrinsics::atomic_nand::<T, U, { AO::Relaxed }>(dst, val),
4166+
Acquire => intrinsics::atomic_nand::<T, U, { AO::Acquire }>(dst, val),
4167+
Release => intrinsics::atomic_nand::<T, U, { AO::Release }>(dst, val),
4168+
AcqRel => intrinsics::atomic_nand::<T, U, { AO::AcqRel }>(dst, val),
4169+
SeqCst => intrinsics::atomic_nand::<T, U, { AO::SeqCst }>(dst, val),
41694170
}
41704171
}
41714172
}
41724173

41734174
#[inline]
41744175
#[cfg(target_has_atomic)]
41754176
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4176-
unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4177+
unsafe fn atomic_or<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
41774178
// SAFETY: the caller must uphold the safety contract for `atomic_or`
41784179
unsafe {
41794180
match order {
4180-
SeqCst => intrinsics::atomic_or::<T, { AO::SeqCst }>(dst, val),
4181-
Acquire => intrinsics::atomic_or::<T, { AO::Acquire }>(dst, val),
4182-
Release => intrinsics::atomic_or::<T, { AO::Release }>(dst, val),
4183-
AcqRel => intrinsics::atomic_or::<T, { AO::AcqRel }>(dst, val),
4184-
Relaxed => intrinsics::atomic_or::<T, { AO::Relaxed }>(dst, val),
4181+
SeqCst => intrinsics::atomic_or::<T, U, { AO::SeqCst }>(dst, val),
4182+
Acquire => intrinsics::atomic_or::<T, U, { AO::Acquire }>(dst, val),
4183+
Release => intrinsics::atomic_or::<T, U, { AO::Release }>(dst, val),
4184+
AcqRel => intrinsics::atomic_or::<T, U, { AO::AcqRel }>(dst, val),
4185+
Relaxed => intrinsics::atomic_or::<T, U, { AO::Relaxed }>(dst, val),
41854186
}
41864187
}
41874188
}
41884189

41894190
#[inline]
41904191
#[cfg(target_has_atomic)]
41914192
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4192-
unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4193+
unsafe fn atomic_xor<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
41934194
// SAFETY: the caller must uphold the safety contract for `atomic_xor`
41944195
unsafe {
41954196
match order {
4196-
SeqCst => intrinsics::atomic_xor::<T, { AO::SeqCst }>(dst, val),
4197-
Acquire => intrinsics::atomic_xor::<T, { AO::Acquire }>(dst, val),
4198-
Release => intrinsics::atomic_xor::<T, { AO::Release }>(dst, val),
4199-
AcqRel => intrinsics::atomic_xor::<T, { AO::AcqRel }>(dst, val),
4200-
Relaxed => intrinsics::atomic_xor::<T, { AO::Relaxed }>(dst, val),
4197+
SeqCst => intrinsics::atomic_xor::<T, U, { AO::SeqCst }>(dst, val),
4198+
Acquire => intrinsics::atomic_xor::<T, U, { AO::Acquire }>(dst, val),
4199+
Release => intrinsics::atomic_xor::<T, U, { AO::Release }>(dst, val),
4200+
AcqRel => intrinsics::atomic_xor::<T, U, { AO::AcqRel }>(dst, val),
4201+
Relaxed => intrinsics::atomic_xor::<T, U, { AO::Relaxed }>(dst, val),
42014202
}
42024203
}
42034204
}

0 commit comments

Comments
 (0)