@@ -340,6 +340,32 @@ impl AtomicBool {
340340 unsafe { & mut * ( v as * mut bool as * mut Self ) }
341341 }
342342
343+ /// Get atomic access to a `&mut [bool]` slice.
344+ ///
345+ /// # Examples
346+ ///
347+ /// ```
348+ /// #![feature(atomic_from_mut, scoped_threads)]
349+ /// use std::sync::atomic::{AtomicBool, Ordering};
350+ ///
351+ /// let mut some_bools = [false; 10];
352+ /// let a = &*AtomicBool::from_mut_slice(&mut some_bools);
353+ /// std::thread::scope(|s| {
354+ /// for i in 0..a.len() {
355+ /// s.spawn(move |_| a[i].store(true, Ordering::Relaxed));
356+ /// }
357+ /// });
358+ /// assert_eq!(some_bools, [true; 10]);
359+ /// ```
360+ #[ inline]
361+ #[ cfg( target_has_atomic_equal_alignment = "8" ) ]
362+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
363+ pub fn from_mut_slice ( v : & mut [ bool ] ) -> & mut [ Self ] {
364+ // SAFETY: the mutable reference guarantees unique ownership, and
365+ // alignment of both `bool` and `Self` is 1.
366+ unsafe { & mut * ( v as * mut [ bool ] as * mut [ Self ] ) }
367+ }
368+
343369 /// Consumes the atomic and returns the contained value.
344370 ///
345371 /// This is safe because passing `self` by value guarantees that no other threads are
@@ -945,6 +971,42 @@ impl<T> AtomicPtr<T> {
945971 unsafe { & mut * ( v as * mut * mut T as * mut Self ) }
946972 }
947973
974+ /// Get atomic access to a slice of pointers.
975+ ///
976+ /// # Examples
977+ ///
978+ /// ```
979+ /// #![feature(atomic_from_mut, scoped_threads)]
980+ /// use std::ptr::null_mut;
981+ /// use std::sync::atomic::{AtomicPtr, Ordering};
982+ ///
983+ /// let mut some_ptrs = [null_mut::<String>(); 10];
984+ /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
985+ /// std::thread::scope(|s| {
986+ /// for i in 0..a.len() {
987+ /// s.spawn(move |_| {
988+ /// let name = Box::new(format!("thread{i}"));
989+ /// a[i].store(Box::into_raw(name), Ordering::Relaxed);
990+ /// });
991+ /// }
992+ /// });
993+ /// for p in some_ptrs {
994+ /// assert!(!p.is_null());
995+ /// let name = unsafe { Box::from_raw(p) };
996+ /// println!("Hello, {name}!");
997+ /// }
998+ /// ```
999+ #[ inline]
1000+ #[ cfg( target_has_atomic_equal_alignment = "ptr" ) ]
1001+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
1002+ pub fn from_mut_slice ( v : & mut [ * mut T ] ) -> & mut [ Self ] {
1003+ // SAFETY:
1004+ // - the mutable reference guarantees unique ownership.
1005+ // - the alignment of `*mut T` and `Self` is the same on all platforms
1006+ // supported by rust, as verified above.
1007+ unsafe { & mut * ( v as * mut [ * mut T ] as * mut [ Self ] ) }
1008+ }
1009+
9481010 /// Consumes the atomic and returns the contained value.
9491011 ///
9501012 /// This is safe because passing `self` by value guarantees that no other threads are
@@ -1459,6 +1521,38 @@ macro_rules! atomic_int {
14591521 unsafe { & mut * ( v as * mut $int_type as * mut Self ) }
14601522 }
14611523
1524+ #[ doc = concat!( "Get atomic access to a `&mut [" , stringify!( $int_type) , "]` slice." ) ]
1525+ ///
1526+ /// # Examples
1527+ ///
1528+ /// ```
1529+ /// #![feature(atomic_from_mut, scoped_threads)]
1530+ #[ doc = concat!( $extra_feature, "use std::sync::atomic::{" , stringify!( $atomic_type) , ", Ordering};" ) ]
1531+ ///
1532+ /// let mut some_ints = [0; 10];
1533+ #[ doc = concat!( "let a = &*" , stringify!( $atomic_type) , "::from_mut_slice(&mut some_ints);" ) ]
1534+ /// std::thread::scope(|s| {
1535+ /// for i in 0..a.len() {
1536+ /// s.spawn(move |_| a[i].store(i as _, Ordering::Relaxed));
1537+ /// }
1538+ /// });
1539+ /// for (i, n) in some_ints.into_iter().enumerate() {
1540+ /// assert_eq!(i, n as usize);
1541+ /// }
1542+ /// ```
1543+ #[ inline]
1544+ #[ $cfg_align]
1545+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
1546+ pub fn from_mut_slice( v: & mut [ $int_type] ) -> & mut [ Self ] {
1547+ use crate :: mem:: align_of;
1548+ let [ ] = [ ( ) ; align_of:: <Self >( ) - align_of:: <$int_type>( ) ] ;
1549+ // SAFETY:
1550+ // - the mutable reference guarantees unique ownership.
1551+ // - the alignment of `$int_type` and `Self` is the
1552+ // same, as promised by $cfg_align and verified above.
1553+ unsafe { & mut * ( v as * mut [ $int_type] as * mut [ Self ] ) }
1554+ }
1555+
14621556 /// Consumes the atomic and returns the contained value.
14631557 ///
14641558 /// This is safe because passing `self` by value guarantees that no other threads are
0 commit comments