@@ -327,6 +327,28 @@ impl AtomicBool {
327
327
unsafe { & mut * ( self . v . get ( ) as * mut bool ) }
328
328
}
329
329
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
+
330
352
/// Consumes the atomic and returns the contained value.
331
353
///
332
354
/// This is safe because passing `self` by value guarantees that no other threads are
@@ -819,6 +841,32 @@ impl<T> AtomicPtr<T> {
819
841
self . p . get_mut ( )
820
842
}
821
843
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
+
822
870
/// Consumes the atomic and returns the contained value.
823
871
///
824
872
/// This is safe because passing `self` by value guarantees that no other threads are
@@ -1113,6 +1161,7 @@ macro_rules! if_not_8_bit {
1113
1161
#[ cfg( target_has_atomic_load_store = "8" ) ]
1114
1162
macro_rules! atomic_int {
1115
1163
( $cfg_cas: meta,
1164
+ $cfg_align: meta,
1116
1165
$stable: meta,
1117
1166
$stable_cxchg: meta,
1118
1167
$stable_debug: meta,
@@ -1231,6 +1280,45 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
1231
1280
}
1232
1281
}
1233
1282
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
+
1234
1322
doc_comment! {
1235
1323
concat!( "Consumes the atomic and returns the contained value.
1236
1324
@@ -1873,6 +1961,7 @@ let mut atomic = ", stringify!($atomic_type), "::new(1);
1873
1961
#[ cfg( target_has_atomic_load_store = "8" ) ]
1874
1962
atomic_int ! {
1875
1963
cfg( target_has_atomic = "8" ) ,
1964
+ cfg( target_has_atomic_equal_alignment = "8" ) ,
1876
1965
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1877
1966
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1878
1967
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1891,6 +1980,7 @@ atomic_int! {
1891
1980
#[ cfg( target_has_atomic_load_store = "8" ) ]
1892
1981
atomic_int ! {
1893
1982
cfg( target_has_atomic = "8" ) ,
1983
+ cfg( target_has_atomic_equal_alignment = "8" ) ,
1894
1984
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1895
1985
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1896
1986
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1909,6 +1999,7 @@ atomic_int! {
1909
1999
#[ cfg( target_has_atomic_load_store = "16" ) ]
1910
2000
atomic_int ! {
1911
2001
cfg( target_has_atomic = "16" ) ,
2002
+ cfg( target_has_atomic_equal_alignment = "16" ) ,
1912
2003
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1913
2004
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1914
2005
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1927,6 +2018,7 @@ atomic_int! {
1927
2018
#[ cfg( target_has_atomic_load_store = "16" ) ]
1928
2019
atomic_int ! {
1929
2020
cfg( target_has_atomic = "16" ) ,
2021
+ cfg( target_has_atomic_equal_alignment = "16" ) ,
1930
2022
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1931
2023
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1932
2024
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1945,6 +2037,7 @@ atomic_int! {
1945
2037
#[ cfg( target_has_atomic_load_store = "32" ) ]
1946
2038
atomic_int ! {
1947
2039
cfg( target_has_atomic = "32" ) ,
2040
+ cfg( target_has_atomic_equal_alignment = "32" ) ,
1948
2041
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1949
2042
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1950
2043
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1963,6 +2056,7 @@ atomic_int! {
1963
2056
#[ cfg( target_has_atomic_load_store = "32" ) ]
1964
2057
atomic_int ! {
1965
2058
cfg( target_has_atomic = "32" ) ,
2059
+ cfg( target_has_atomic_equal_alignment = "32" ) ,
1966
2060
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1967
2061
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1968
2062
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1981,6 +2075,7 @@ atomic_int! {
1981
2075
#[ cfg( target_has_atomic_load_store = "64" ) ]
1982
2076
atomic_int ! {
1983
2077
cfg( target_has_atomic = "64" ) ,
2078
+ cfg( target_has_atomic_equal_alignment = "64" ) ,
1984
2079
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1985
2080
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1986
2081
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -1999,6 +2094,7 @@ atomic_int! {
1999
2094
#[ cfg( target_has_atomic_load_store = "64" ) ]
2000
2095
atomic_int ! {
2001
2096
cfg( target_has_atomic = "64" ) ,
2097
+ cfg( target_has_atomic_equal_alignment = "64" ) ,
2002
2098
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
2003
2099
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
2004
2100
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
@@ -2017,6 +2113,7 @@ atomic_int! {
2017
2113
#[ cfg( target_has_atomic_load_store = "128" ) ]
2018
2114
atomic_int ! {
2019
2115
cfg( target_has_atomic = "128" ) ,
2116
+ cfg( target_has_atomic_equal_alignment = "128" ) ,
2020
2117
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2021
2118
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2022
2119
unstable( feature = "integer_atomics" , issue = "32976" ) ,
@@ -2035,6 +2132,7 @@ atomic_int! {
2035
2132
#[ cfg( target_has_atomic_load_store = "128" ) ]
2036
2133
atomic_int ! {
2037
2134
cfg( target_has_atomic = "128" ) ,
2135
+ cfg( target_has_atomic_equal_alignment = "128" ) ,
2038
2136
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2039
2137
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2040
2138
unstable( feature = "integer_atomics" , issue = "32976" ) ,
@@ -2074,6 +2172,7 @@ macro_rules! ptr_width {
2074
2172
#[ cfg( target_has_atomic_load_store = "ptr" ) ]
2075
2173
atomic_int ! {
2076
2174
cfg( target_has_atomic = "ptr" ) ,
2175
+ cfg( target_has_atomic_equal_alignment = "ptr" ) ,
2077
2176
stable( feature = "rust1" , since = "1.0.0" ) ,
2078
2177
stable( feature = "extended_compare_and_swap" , since = "1.10.0" ) ,
2079
2178
stable( feature = "atomic_debug" , since = "1.3.0" ) ,
@@ -2092,6 +2191,7 @@ atomic_int! {
2092
2191
#[ cfg( target_has_atomic_load_store = "ptr" ) ]
2093
2192
atomic_int ! {
2094
2193
cfg( target_has_atomic = "ptr" ) ,
2194
+ cfg( target_has_atomic_equal_alignment = "ptr" ) ,
2095
2195
stable( feature = "rust1" , since = "1.0.0" ) ,
2096
2196
stable( feature = "extended_compare_and_swap" , since = "1.10.0" ) ,
2097
2197
stable( feature = "atomic_debug" , since = "1.3.0" ) ,
0 commit comments