@@ -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
@@ -820,6 +842,30 @@ impl<T> AtomicPtr<T> {
820842 unsafe { & mut * self . p . get ( ) }
821843 }
822844
845+ /// Get atomic access to a pointer.
846+ ///
847+ /// # Examples
848+ ///
849+ /// ```
850+ /// #![feature(atomic_from_mut)]
851+ /// use std::sync::atomic::{AtomicPtr, Ordering};
852+ ///
853+ /// let mut some_ptr = &mut 123 as *mut i32;
854+ /// let a = AtomicPtr::from_mut(&mut some_ptr);
855+ /// a.store(&mut 456, Ordering::Relaxed);
856+ /// assert_eq!(unsafe { *some_ptr }, 456);
857+ /// ```
858+ #[ inline]
859+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
860+ pub fn from_mut ( v : & mut * mut T ) -> & Self {
861+ let [ ] = [ ( ) ; align_of :: < Self > ( ) - align_of :: < * mut T > ( ) ] ;
862+ // SAFETY:
863+ // - the mutable reference guarantees unique ownership.
864+ // - the alignment of `*mut T` and `Self` is the same on all platforms
865+ // supported by rust, as verified above.
866+ unsafe { & * ( v as * mut * mut T as * mut Self ) }
867+ }
868+
823869 /// Consumes the atomic and returns the contained value.
824870 ///
825871 /// This is safe because passing `self` by value guarantees that no other threads are
@@ -1104,6 +1150,12 @@ impl<T> From<*mut T> for AtomicPtr<T> {
11041150 }
11051151}
11061152
1153+ macro_rules! if_not_8_bit {
1154+ ( u8 , $( $tt: tt) * ) => { "" } ;
1155+ ( i8 , $( $tt: tt) * ) => { "" } ;
1156+ ( $_: ident, $( $tt: tt) * ) => { $( $tt) * } ;
1157+ }
1158+
11071159#[ cfg( target_has_atomic_load_store = "8" ) ]
11081160macro_rules! atomic_int {
11091161 ( $cfg_cas: meta,
@@ -1115,7 +1167,8 @@ macro_rules! atomic_int {
11151167 $stable_nand: meta,
11161168 $const_stable: meta,
11171169 $stable_init_const: meta,
1118- $s_int_type: expr, $int_ref: expr,
1170+ $( from_mut: cfg( $from_mut_cfg: meta) , ) ?
1171+ $s_int_type: literal, $int_ref: expr,
11191172 $extra_feature: expr,
11201173 $min_fn: ident, $max_fn: ident,
11211174 $align: expr,
@@ -1226,6 +1279,45 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
12261279 }
12271280 }
12281281
1282+ doc_comment! {
1283+ concat!( "Get atomic access to a `&mut " , stringify!( $int_type) , "`.
1284+
1285+ " ,
1286+ if_not_8_bit! {
1287+ $int_type,
1288+ concat!(
1289+ "**Note:** This function is only available on targets where `" ,
1290+ stringify!( $int_type) , "` has an alignment of " , $align, " bytes."
1291+ )
1292+ } ,
1293+ "
1294+
1295+ # Examples
1296+
1297+ ```
1298+ #![feature(atomic_from_mut)]
1299+ " , $extra_feature, "use std::sync::atomic::{" , stringify!( $atomic_type) , ", Ordering};
1300+
1301+ let mut some_int = 123;
1302+ let a = " , stringify!( $atomic_type) , "::from_mut(&mut some_int);
1303+ a.store(100, Ordering::Relaxed);
1304+ assert_eq!(some_int, 100);
1305+ ```
1306+ " ) ,
1307+ #[ inline]
1308+ $( #[ cfg( $from_mut_cfg) ] ) ?
1309+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
1310+ pub fn from_mut( v: & mut $int_type) -> & Self {
1311+ let [ ] = [ ( ) ; align_of:: <Self >( ) - align_of:: <$int_type>( ) ] ;
1312+ // SAFETY:
1313+ // - the mutable reference guarantees unique ownership.
1314+ // - the alignment of `$int_type` and `Self` is the
1315+ // same on all platforms enabled by `$from_mut_cfg`
1316+ // as verified above.
1317+ unsafe { & * ( v as * mut $int_type as * mut Self ) }
1318+ }
1319+ }
1320+
12291321 doc_comment! {
12301322 concat!( "Consumes the atomic and returns the contained value.
12311323
@@ -1984,6 +2076,7 @@ atomic_int! {
19842076 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19852077 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
19862078 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2079+ from_mut: cfg( not( target_arch = "x86" ) ) ,
19872080 "i64" , "../../../std/primitive.i64.html" ,
19882081 "" ,
19892082 atomic_min, atomic_max,
@@ -2002,6 +2095,7 @@ atomic_int! {
20022095 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
20032096 rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
20042097 unstable( feature = "integer_atomics" , issue = "32976" ) ,
2098+ from_mut: cfg( not( target_arch = "x86" ) ) ,
20052099 "u64" , "../../../std/primitive.u64.html" ,
20062100 "" ,
20072101 atomic_umin, atomic_umax,
0 commit comments