@@ -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