From a513c84a5b54e83b158d0083385864c37cca358c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 12 Jan 2023 07:27:36 +0000 Subject: [PATCH] Add `AtomicPtr::as_mut_ptr` --- library/core/src/sync/atomic.rs | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index edc68d6fae5..8a7c3c3c303 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1786,6 +1786,42 @@ pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast() } } + + /// Returns a mutable pointer to the underlying pointer. + /// + /// Doing non-atomic reads and writes on the resulting integer can be a data race. + /// This method is mostly useful for FFI, where the function signature may use + /// `*mut *mut T` instead of `&AtomicPtr`. + /// + /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the + /// atomic types work with interior mutability. All modifications of an atomic change the value + /// through a shared reference, and can do so safely as long as they use atomic operations. Any + /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same + /// restriction: operations on it must be atomic. + /// + /// # Examples + /// + /// ```ignore (extern-declaration) + /// #![feature(atomic_mut_ptr)] + //// use std::sync::atomic::AtomicPtr; + /// + /// extern "C" { + /// fn my_atomic_op(arg: *mut *mut u32); + /// } + /// + /// let mut value = 17; + /// let atomic = AtomicPtr::new(&mut value); + /// + /// // SAFETY: Safe as long as `my_atomic_op` is atomic. + /// unsafe { + /// my_atomic_op(atomic.as_mut_ptr()); + /// } + /// ``` + #[inline] + #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")] + pub fn as_mut_ptr(&self) -> *mut *mut T { + self.p.get() + } } #[cfg(target_has_atomic_load_store = "8")] -- 2.44.0