Skip to content

Commit 9b502a4

Browse files
author
Yuki Okushi
authored
Rollup merge of #106762 - WaffleLapkin:atomicptr+as_mut_ptr, r=m-ou-se
Add `AtomicPtr::as_mut_ptr` See #66893 (comment) r? thomcc
2 parents 6486b02 + 22b4c68 commit 9b502a4

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

library/core/src/sync/atomic.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -1786,6 +1786,42 @@ impl<T> AtomicPtr<T> {
17861786
// SAFETY: data races are prevented by atomic intrinsics.
17871787
unsafe { atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
17881788
}
1789+
1790+
/// Returns a mutable pointer to the underlying pointer.
1791+
///
1792+
/// Doing non-atomic reads and writes on the resulting integer can be a data race.
1793+
/// This method is mostly useful for FFI, where the function signature may use
1794+
/// `*mut *mut T` instead of `&AtomicPtr<T>`.
1795+
///
1796+
/// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
1797+
/// atomic types work with interior mutability. All modifications of an atomic change the value
1798+
/// through a shared reference, and can do so safely as long as they use atomic operations. Any
1799+
/// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
1800+
/// restriction: operations on it must be atomic.
1801+
///
1802+
/// # Examples
1803+
///
1804+
/// ```ignore (extern-declaration)
1805+
/// #![feature(atomic_mut_ptr)]
1806+
//// use std::sync::atomic::AtomicPtr;
1807+
///
1808+
/// extern "C" {
1809+
/// fn my_atomic_op(arg: *mut *mut u32);
1810+
/// }
1811+
///
1812+
/// let mut value = 17;
1813+
/// let atomic = AtomicPtr::new(&mut value);
1814+
///
1815+
/// // SAFETY: Safe as long as `my_atomic_op` is atomic.
1816+
/// unsafe {
1817+
/// my_atomic_op(atomic.as_mut_ptr());
1818+
/// }
1819+
/// ```
1820+
#[inline]
1821+
#[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
1822+
pub fn as_mut_ptr(&self) -> *mut *mut T {
1823+
self.p.get()
1824+
}
17891825
}
17901826

17911827
#[cfg(target_has_atomic_load_store = "8")]
@@ -2678,9 +2714,9 @@ macro_rules! atomic_int {
26782714
#[doc = concat!(" fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
26792715
/// }
26802716
///
2681-
#[doc = concat!("let mut atomic = ", stringify!($atomic_type), "::new(1);")]
2717+
#[doc = concat!("let atomic = ", stringify!($atomic_type), "::new(1);")]
26822718
///
2683-
// SAFETY: Safe as long as `my_atomic_op` is atomic.
2719+
/// // SAFETY: Safe as long as `my_atomic_op` is atomic.
26842720
/// unsafe {
26852721
/// my_atomic_op(atomic.as_mut_ptr());
26862722
/// }

0 commit comments

Comments
 (0)