@@ -327,6 +327,28 @@ impl AtomicBool {
327327 unsafe { & mut * ( self . v . get ( ) as * mut bool ) }
328328 }
329329
330+ /// Get atomic access to a `&mut bool`.
331+ ///
332+ /// # Examples
333+ ///
334+ /// ```
335+ /// #![feature(atomic_from_mut)]
336+ /// use std::sync::atomic::{AtomicBool, Ordering};
337+ ///
338+ /// let mut some_bool = true;
339+ /// let a = AtomicBool::from_mut(&mut some_bool);
340+ /// a.store(false, Ordering::Relaxed);
341+ /// assert_eq!(some_bool, false);
342+ /// ```
343+ #[ inline]
344+ #[ cfg( target_has_atomic_equal_alignment = "8" ) ]
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,32 @@ 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+ #[ cfg( target_has_atomic_equal_alignment = "ptr" ) ]
859+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
860+ pub fn from_mut ( v : & mut * mut T ) -> & Self {
861+ use crate :: mem:: align_of;
862+ let [ ] = [ ( ) ; align_of :: < AtomicPtr < ( ) > > ( ) - align_of :: < * mut ( ) > ( ) ] ;
863+ // SAFETY:
864+ // - the mutable reference guarantees unique ownership.
865+ // - the alignment of `*mut T` and `Self` is the same on all platforms
866+ // supported by rust, as verified above.
867+ unsafe { & * ( v as * mut * mut T as * mut Self ) }
868+ }
869+
822870 /// Consumes the atomic and returns the contained value.
823871 ///
824872 /// This is safe because passing `self` by value guarantees that no other threads are
@@ -1113,6 +1161,7 @@ macro_rules! if_not_8_bit {
11131161#[ cfg( target_has_atomic_load_store = "8" ) ]
11141162macro_rules! atomic_int {
11151163 ( $cfg_cas: meta,
1164+ $cfg_align: meta,
11161165 $stable: meta,
11171166 $stable_cxchg: meta,
11181167 $stable_debug: meta,
@@ -1231,6 +1280,45 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
12311280 }
12321281 }
12331282
1283+ doc_comment! {
1284+ concat!( "Get atomic access to a `&mut " , stringify!( $int_type) , "`.
1285+
1286+ " ,
1287+ if_not_8_bit! {
1288+ $int_type,
1289+ concat!(
1290+ "**Note:** This function is only available on targets where `" ,
1291+ stringify!( $int_type) , "` has an alignment of " , $align, " bytes."
1292+ )
1293+ } ,
1294+ "
1295+
1296+ # Examples
1297+
1298+ ```
1299+ #![feature(atomic_from_mut)]
1300+ " , $extra_feature, "use std::sync::atomic::{" , stringify!( $atomic_type) , ", Ordering};
1301+
1302+ let mut some_int = 123;
1303+ let a = " , stringify!( $atomic_type) , "::from_mut(&mut some_int);
1304+ a.store(100, Ordering::Relaxed);
1305+ assert_eq!(some_int, 100);
1306+ ```
1307+ " ) ,
1308+ #[ inline]
1309+ #[ $cfg_align]
1310+ #[ unstable( feature = "atomic_from_mut" , issue = "76314" ) ]
1311+ pub fn from_mut( v: & mut $int_type) -> & Self {
1312+ use crate :: mem:: align_of;
1313+ let [ ] = [ ( ) ; align_of:: <Self >( ) - align_of:: <$int_type>( ) ] ;
1314+ // SAFETY:
1315+ // - the mutable reference guarantees unique ownership.
1316+ // - the alignment of `$int_type` and `Self` is the
1317+ // same, as promised by $cfg_align and verified above.
1318+ unsafe { & * ( v as * mut $int_type as * mut Self ) }
1319+ }
1320+ }
1321+
12341322 doc_comment! {
12351323 concat!( "Consumes the atomic and returns the contained value.
12361324
@@ -1873,6 +1961,7 @@ let mut atomic = ", stringify!($atomic_type), "::new(1);
18731961#[ cfg( target_has_atomic_load_store = "8" ) ]
18741962atomic_int ! {
18751963 cfg( target_has_atomic = "8" ) ,
1964+ cfg( target_has_atomic_equal_alignment = "8" ) ,
18761965 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
18771966 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
18781967 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1891,6 +1980,7 @@ atomic_int! {
18911980#[ cfg( target_has_atomic_load_store = "8" ) ]
18921981atomic_int ! {
18931982 cfg( target_has_atomic = "8" ) ,
1983+ cfg( target_has_atomic_equal_alignment = "8" ) ,
18941984 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
18951985 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
18961986 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1909,6 +1999,7 @@ atomic_int! {
19091999#[ cfg( target_has_atomic_load_store = "16" ) ]
19102000atomic_int ! {
19112001 cfg( target_has_atomic = "16" ) ,
2002+ cfg( target_has_atomic_equal_alignment = "16" ) ,
19122003 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19132004 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19142005 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1927,6 +2018,7 @@ atomic_int! {
19272018#[ cfg( target_has_atomic_load_store = "16" ) ]
19282019atomic_int ! {
19292020 cfg( target_has_atomic = "16" ) ,
2021+ cfg( target_has_atomic_equal_alignment = "16" ) ,
19302022 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19312023 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19322024 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1945,6 +2037,7 @@ atomic_int! {
19452037#[ cfg( target_has_atomic_load_store = "32" ) ]
19462038atomic_int ! {
19472039 cfg( target_has_atomic = "32" ) ,
2040+ cfg( target_has_atomic_equal_alignment = "32" ) ,
19482041 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19492042 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19502043 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1963,6 +2056,7 @@ atomic_int! {
19632056#[ cfg( target_has_atomic_load_store = "32" ) ]
19642057atomic_int ! {
19652058 cfg( target_has_atomic = "32" ) ,
2059+ cfg( target_has_atomic_equal_alignment = "32" ) ,
19662060 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19672061 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19682062 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1981,6 +2075,7 @@ atomic_int! {
19812075#[ cfg( target_has_atomic_load_store = "64" ) ]
19822076atomic_int ! {
19832077 cfg( target_has_atomic = "64" ) ,
2078+ cfg( target_has_atomic_equal_alignment = "64" ) ,
19842079 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19852080 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
19862081 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1999,6 +2094,7 @@ atomic_int! {
19992094#[ cfg( target_has_atomic_load_store = "64" ) ]
20002095atomic_int ! {
20012096 cfg( target_has_atomic = "64" ) ,
2097+ cfg( target_has_atomic_equal_alignment = "64" ) ,
20022098 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
20032099 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
20042100 stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -2017,6 +2113,7 @@ atomic_int! {
20172113#[ cfg( target_has_atomic_load_store = "128" ) ]
20182114atomic_int ! {
20192115 cfg( target_has_atomic = "128" ) ,
2116+ cfg( target_has_atomic_equal_alignment = "128" ) ,
20202117 unstable( feature = "integer_atomics" , issue = "32976" ) ,
20212118 unstable( feature = "integer_atomics" , issue = "32976" ) ,
20222119 unstable( feature = "integer_atomics" , issue = "32976" ) ,
@@ -2035,6 +2132,7 @@ atomic_int! {
20352132#[ cfg( target_has_atomic_load_store = "128" ) ]
20362133atomic_int ! {
20372134 cfg( target_has_atomic = "128" ) ,
2135+ cfg( target_has_atomic_equal_alignment = "128" ) ,
20382136 unstable( feature = "integer_atomics" , issue = "32976" ) ,
20392137 unstable( feature = "integer_atomics" , issue = "32976" ) ,
20402138 unstable( feature = "integer_atomics" , issue = "32976" ) ,
@@ -2074,6 +2172,7 @@ macro_rules! ptr_width {
20742172#[ cfg( target_has_atomic_load_store = "ptr" ) ]
20752173atomic_int ! {
20762174 cfg( target_has_atomic = "ptr" ) ,
2175+ cfg( target_has_atomic_equal_alignment = "ptr" ) ,
20772176 stable( feature = "rust1" , since = "1.0.0" ) ,
20782177 stable( feature = "extended_compare_and_swap" , since = "1.10.0" ) ,
20792178 stable( feature = "atomic_debug" , since = "1.3.0" ) ,
@@ -2092,6 +2191,7 @@ atomic_int! {
20922191#[ cfg( target_has_atomic_load_store = "ptr" ) ]
20932192atomic_int ! {
20942193 cfg( target_has_atomic = "ptr" ) ,
2194+ cfg( target_has_atomic_equal_alignment = "ptr" ) ,
20952195 stable( feature = "rust1" , since = "1.0.0" ) ,
20962196 stable( feature = "extended_compare_and_swap" , since = "1.10.0" ) ,
20972197 stable( feature = "atomic_debug" , since = "1.3.0" ) ,
0 commit comments