@@ -110,6 +110,7 @@ use self::Ordering::*;
110110use crate :: cell:: UnsafeCell ;
111111use crate :: fmt;
112112use crate :: intrinsics;
113+ use crate :: mem:: align_of;
113114
114115use crate :: hint:: spin_loop;
115116
@@ -327,6 +328,27 @@ impl AtomicBool {
327328 unsafe { & mut * ( self . v . get ( ) as * mut bool ) }
328329 }
329330
331+ /// Get atomic access to a `&mut bool`.
332+ ///
333+ /// # Examples
334+ ///
335+ /// ```
336+ /// #![feature(atomic_from_mut)]
337+ /// use std::sync::atomic::{AtomicBool, Ordering};
338+ ///
339+ /// let mut some_bool = true;
340+ /// let a = AtomicBool::from_mut(&mut some_bool);
341+ /// a.store(false, Ordering::Relaxed);
342+ /// assert_eq!(some_bool, false);
343+ /// ```
344+ #[ inline]
345+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
346+ pub fn from_mut ( v : & mut bool ) -> & Self {
347+ // SAFETY: the mutable reference guarantees unique ownership, and
348+ // alignment of both `bool` and `Self` is 1.
349+ unsafe { & * ( v as * mut bool as * mut Self ) }
350+ }
351+
330352 /// Consumes the atomic and returns the contained value.
331353 ///
332354 /// This is safe because passing `self` by value guarantees that no other threads are
@@ -819,6 +841,30 @@ impl<T> AtomicPtr<T> {
819841 self . p . get_mut ( )
820842 }
821843
844+ /// Get atomic access to a pointer.
845+ ///
846+ /// # Examples
847+ ///
848+ /// ```
849+ /// #![feature(atomic_from_mut)]
850+ /// use std::sync::atomic::{AtomicPtr, Ordering};
851+ ///
852+ /// let mut some_ptr = &mut 123 as *mut i32;
853+ /// let a = AtomicPtr::from_mut(&mut some_ptr);
854+ /// a.store(&mut 456, Ordering::Relaxed);
855+ /// assert_eq!(unsafe { *some_ptr }, 456);
856+ /// ```
857+ #[ inline]
858+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
859+ pub fn from_mut ( v : & mut * mut T ) -> & Self {
860+ let [ ] = [ ( ) ; align_of :: < AtomicPtr < ( ) > > ( ) - align_of :: < * mut ( ) > ( ) ] ;
861+ // SAFETY:
862+ // - the mutable reference guarantees unique ownership.
863+ // - the alignment of `*mut T` and `Self` is the same on all platforms
864+ // supported by rust, as verified above.
865+ unsafe { & * ( v as * mut * mut T as * mut Self ) }
866+ }
867+
822868 /// Consumes the atomic and returns the contained value.
823869 ///
824870 /// This is safe because passing `self` by value guarantees that no other threads are
@@ -1121,6 +1167,7 @@ macro_rules! atomic_int {
11211167 $stable_nand: meta,
11221168 $const_stable: meta,
11231169 $stable_init_const: meta,
1170+ $( from_mut: cfg( $from_mut_cfg: meta) , ) ?
11241171 $s_int_type: literal, $int_ref: expr,
11251172 $extra_feature: expr,
11261173 $min_fn: ident, $max_fn: ident,
@@ -1231,6 +1278,45 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
12311278 }
12321279 }
12331280
1281+ doc_comment! {
1282+ concat!( "Get atomic access to a `&mut " , stringify!( $int_type) , "`.
1283+
1284+ " ,
1285+ if_not_8_bit! {
1286+ $int_type,
1287+ concat!(
1288+ "**Note:** This function is only available on targets where `" ,
1289+ stringify!( $int_type) , "` has an alignment of " , $align, " bytes."
1290+ )
1291+ } ,
1292+ "
1293+
1294+ # Examples
1295+
1296+ ```
1297+ #![feature(atomic_from_mut)]
1298+ " , $extra_feature, "use std::sync::atomic::{" , stringify!( $atomic_type) , ", Ordering};
1299+
1300+ let mut some_int = 123;
1301+ let a = " , stringify!( $atomic_type) , "::from_mut(&mut some_int);
1302+ a.store(100, Ordering::Relaxed);
1303+ assert_eq!(some_int, 100);
1304+ ```
1305+ " ) ,
1306+ #[ inline]
1307+ $( #[ cfg( $from_mut_cfg) ] ) ?
1308+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
1309+ pub fn from_mut( v: & mut $int_type) -> & Self {
1310+ let [ ] = [ ( ) ; align_of:: <Self >( ) - align_of:: <$int_type>( ) ] ;
1311+ // SAFETY:
1312+ // - the mutable reference guarantees unique ownership.
1313+ // - the alignment of `$int_type` and `Self` is the
1314+ // same on all platforms enabled by `$from_mut_cfg`
1315+ // as verified above.
1316+ unsafe { & * ( v as * mut $int_type as * mut Self ) }
1317+ }
1318+ }
1319+
12341320 doc_comment! {
12351321 concat!( "Consumes the atomic and returns the contained value.
12361322
@@ -1989,6 +2075,7 @@ atomic_int! {
19892075 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19902076 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
19912077 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2078+ from_mut: cfg( not( target_arch = "x86" ) ) ,
19922079 "i64" , "../../../std/primitive.i64.html" ,
19932080 "" ,
19942081 atomic_min, atomic_max,
@@ -2007,6 +2094,7 @@ atomic_int! {
20072094 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
20082095 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
20092096 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2097+ from_mut: cfg( not( target_arch = "x86" ) ) ,
20102098 "u64" , "../../../std/primitive.u64.html" ,
20112099 "" ,
20122100 atomic_umin, atomic_umax,
@@ -2025,6 +2113,7 @@ atomic_int! {
20252113 unstable( feature = "integer_atomics" , issue = "32976" ) ,
20262114 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
20272115 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2116+ from_mut: cfg( not( target_arch = "x86_64" ) ) ,
20282117 "i128" , "../../../std/primitive.i128.html" ,
20292118 "#![feature(integer_atomics)]\n \n " ,
20302119 atomic_min, atomic_max,
@@ -2043,6 +2132,7 @@ atomic_int! {
20432132 unstable( feature = "integer_atomics" , issue = "32976" ) ,
20442133 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
20452134 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2135+ from_mut: cfg( not( target_arch = "x86_64" ) ) ,
20462136 "u128" , "../../../std/primitive.u128.html" ,
20472137 "#![feature(integer_atomics)]\n \n " ,
20482138 atomic_umin, atomic_umax,
0 commit comments