@@ -340,6 +340,40 @@ impl AtomicBool {
340
340
unsafe { & mut * ( v as * mut bool as * mut Self ) }
341
341
}
342
342
343
+ /// Get non-atomic access to a `&mut [AtomicBool]` slice.
344
+ ///
345
+ /// This is safe because the mutable reference guarantees that no other threads are
346
+ /// concurrently accessing the atomic data.
347
+ ///
348
+ /// # Examples
349
+ ///
350
+ /// ```
351
+ /// #![feature(atomic_from_mut, inline_const, scoped_threads)]
352
+ /// use std::sync::atomic::{AtomicBool, Ordering};
353
+ ///
354
+ /// let mut some_bools = [const { AtomicBool::new(false) }; 10];
355
+ ///
356
+ /// let view: &mut [bool] = AtomicBool::get_mut_slice(&mut some_bools);
357
+ /// assert_eq!(view, [false; 10]);
358
+ /// view[..5].copy_from_slice(&[true; 5]);
359
+ ///
360
+ /// std::thread::scope(|s| {
361
+ /// for t in &some_bools[..5] {
362
+ /// s.spawn(move || assert_eq!(t.load(Ordering::Relaxed), true));
363
+ /// }
364
+ ///
365
+ /// for f in &some_bools[5..] {
366
+ /// s.spawn(move || assert_eq!(f.load(Ordering::Relaxed), false));
367
+ /// }
368
+ /// });
369
+ /// ```
370
+ #[ inline]
371
+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
372
+ pub fn get_mut_slice ( this : & mut [ Self ] ) -> & mut [ bool ] {
373
+ // SAFETY: the mutable reference guarantees unique ownership.
374
+ unsafe { & mut * ( this as * mut [ Self ] as * mut [ bool ] ) }
375
+ }
376
+
343
377
/// Get atomic access to a `&mut [bool]` slice.
344
378
///
345
379
/// # Examples
@@ -971,6 +1005,46 @@ impl<T> AtomicPtr<T> {
971
1005
unsafe { & mut * ( v as * mut * mut T as * mut Self ) }
972
1006
}
973
1007
1008
+ /// Get non-atomic access to a `&mut [AtomicPtr]` slice.
1009
+ ///
1010
+ /// This is safe because the mutable reference guarantees that no other threads are
1011
+ /// concurrently accessing the atomic data.
1012
+ ///
1013
+ /// # Examples
1014
+ ///
1015
+ /// ```
1016
+ /// #![feature(atomic_from_mut, inline_const, scoped_threads)]
1017
+ /// use std::ptr::null_mut;
1018
+ /// use std::sync::atomic::{AtomicPtr, Ordering};
1019
+ ///
1020
+ /// let mut some_ptrs = [const { AtomicPtr::new(null_mut::<String>()) }; 10];
1021
+ ///
1022
+ /// let view: &mut [*mut String] = AtomicPtr::get_mut_slice(&mut some_ptrs);
1023
+ /// assert_eq!(view, [null_mut::<String>(); 10]);
1024
+ /// view
1025
+ /// .iter_mut()
1026
+ /// .enumerate()
1027
+ /// .for_each(|(i, ptr)| *ptr = Box::into_raw(Box::new(format!("iteration#{i}"))));
1028
+ ///
1029
+ /// std::thread::scope(|s| {
1030
+ /// for ptr in &some_ptrs {
1031
+ /// s.spawn(move || {
1032
+ /// let ptr = ptr.load(Ordering::Relaxed);
1033
+ /// assert!(!ptr.is_null());
1034
+ ///
1035
+ /// let name = unsafe { Box::from_raw(ptr) };
1036
+ /// println!("Hello, {name}!");
1037
+ /// });
1038
+ /// }
1039
+ /// });
1040
+ /// ```
1041
+ #[ inline]
1042
+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
1043
+ pub fn get_mut_slice ( this : & mut [ Self ] ) -> & mut [ * mut T ] {
1044
+ // SAFETY: the mutable reference guarantees unique ownership.
1045
+ unsafe { & mut * ( this as * mut [ Self ] as * mut [ * mut T ] ) }
1046
+ }
1047
+
974
1048
/// Get atomic access to a slice of pointers.
975
1049
///
976
1050
/// # Examples
@@ -1521,6 +1595,42 @@ macro_rules! atomic_int {
1521
1595
unsafe { & mut * ( v as * mut $int_type as * mut Self ) }
1522
1596
}
1523
1597
1598
+ #[ doc = concat!( "Get non-atomic access to a `&mut [" , stringify!( $atomic_type) , "]` slice" ) ]
1599
+ ///
1600
+ /// This is safe because the mutable reference guarantees that no other threads are
1601
+ /// concurrently accessing the atomic data.
1602
+ ///
1603
+ /// # Examples
1604
+ ///
1605
+ /// ```
1606
+ /// #![feature(atomic_from_mut, inline_const, scoped_threads)]
1607
+ #[ doc = concat!( $extra_feature, "use std::sync::atomic::{" , stringify!( $atomic_type) , ", Ordering};" ) ]
1608
+ ///
1609
+ #[ doc = concat!( "let mut some_ints = [const { " , stringify!( $atomic_type) , "::new(0) }; 10];" ) ]
1610
+ ///
1611
+ #[ doc = concat!( "let view: &mut [" , stringify!( $int_type) , "] = " , stringify!( $atomic_type) , "::get_mut_slice(&mut some_ints);" ) ]
1612
+ /// assert_eq!(view, [0; 10]);
1613
+ /// view
1614
+ /// .iter_mut()
1615
+ /// .enumerate()
1616
+ /// .for_each(|(idx, int)| *int = idx as _);
1617
+ ///
1618
+ /// std::thread::scope(|s| {
1619
+ /// some_ints
1620
+ /// .iter()
1621
+ /// .enumerate()
1622
+ /// .for_each(|(idx, int)| {
1623
+ /// s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
1624
+ /// })
1625
+ /// });
1626
+ /// ```
1627
+ #[ inline]
1628
+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
1629
+ pub fn get_mut_slice( this: & mut [ Self ] ) -> & mut [ $int_type] {
1630
+ // SAFETY: the mutable reference guarantees unique ownership.
1631
+ unsafe { & mut * ( this as * mut [ Self ] as * mut [ $int_type] ) }
1632
+ }
1633
+
1524
1634
#[ doc = concat!( "Get atomic access to a `&mut [" , stringify!( $int_type) , "]` slice." ) ]
1525
1635
///
1526
1636
/// # Examples
0 commit comments