@@ -340,6 +340,32 @@ impl AtomicBool {
340
340
unsafe { & mut * ( v as * mut bool as * mut Self ) }
341
341
}
342
342
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
+
343
369
/// Consumes the atomic and returns the contained value.
344
370
///
345
371
/// This is safe because passing `self` by value guarantees that no other threads are
@@ -945,6 +971,42 @@ impl<T> AtomicPtr<T> {
945
971
unsafe { & mut * ( v as * mut * mut T as * mut Self ) }
946
972
}
947
973
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
+
948
1010
/// Consumes the atomic and returns the contained value.
949
1011
///
950
1012
/// This is safe because passing `self` by value guarantees that no other threads are
@@ -1459,6 +1521,38 @@ macro_rules! atomic_int {
1459
1521
unsafe { & mut * ( v as * mut $int_type as * mut Self ) }
1460
1522
}
1461
1523
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
+
1462
1556
/// Consumes the atomic and returns the contained value.
1463
1557
///
1464
1558
/// This is safe because passing `self` by value guarantees that no other threads are
0 commit comments