]> git.lizzy.rs Git - rust.git/blobdiff - library/core/src/sync/atomic.rs
Auto merge of #106696 - kylematsuda:early-binder, r=lcnr
[rust.git] / library / core / src / sync / atomic.rs
index cdc47e17938dc38e3e58e343f3015dd9a2545c11..14367eb09bc75e0e00c13ec9a4025638df8630f0 100644 (file)
@@ -294,7 +294,7 @@ impl AtomicBool {
     /// ```
     /// use std::sync::atomic::AtomicBool;
     ///
-    /// let atomic_true  = AtomicBool::new(true);
+    /// let atomic_true = AtomicBool::new(true);
     /// let atomic_false = AtomicBool::new(false);
     /// ```
     #[inline]
@@ -1179,7 +1179,7 @@ pub const fn into_inner(self) -> *mut T {
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let ptr = &mut 5;
-    /// let some_ptr  = AtomicPtr::new(ptr);
+    /// let some_ptr = AtomicPtr::new(ptr);
     ///
     /// let value = some_ptr.load(Ordering::Relaxed);
     /// ```
@@ -1206,7 +1206,7 @@ pub fn load(&self, order: Ordering) -> *mut T {
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let ptr = &mut 5;
-    /// let some_ptr  = AtomicPtr::new(ptr);
+    /// let some_ptr = AtomicPtr::new(ptr);
     ///
     /// let other_ptr = &mut 10;
     ///
@@ -1238,7 +1238,7 @@ pub fn store(&self, ptr: *mut T, order: Ordering) {
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let ptr = &mut 5;
-    /// let some_ptr  = AtomicPtr::new(ptr);
+    /// let some_ptr = AtomicPtr::new(ptr);
     ///
     /// let other_ptr = &mut 10;
     ///
@@ -1290,9 +1290,9 @@ pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let ptr = &mut 5;
-    /// let some_ptr  = AtomicPtr::new(ptr);
+    /// let some_ptr = AtomicPtr::new(ptr);
     ///
-    /// let other_ptr   = &mut 10;
+    /// let other_ptr = &mut 10;
     ///
     /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
     /// ```
@@ -1333,9 +1333,9 @@ pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) ->
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let ptr = &mut 5;
-    /// let some_ptr  = AtomicPtr::new(ptr);
+    /// let some_ptr = AtomicPtr::new(ptr);
     ///
-    /// let other_ptr   = &mut 10;
+    /// let other_ptr = &mut 10;
     ///
     /// let value = some_ptr.compare_exchange(ptr, other_ptr,
     ///                                       Ordering::SeqCst, Ordering::Relaxed);
@@ -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<T>`.
+    ///
+    /// 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")]
@@ -2678,9 +2714,9 @@ pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
             #[doc = concat!("    fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
             /// }
             ///
-            #[doc = concat!("let mut atomic = ", stringify!($atomic_type), "::new(1);")]
+            #[doc = concat!("let atomic = ", stringify!($atomic_type), "::new(1);")]
             ///
-            // SAFETY: Safe as long as `my_atomic_op` is atomic.
+            /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
             /// unsafe {
             ///     my_atomic_op(atomic.as_mut_ptr());
             /// }