@@ -110,6 +110,7 @@ use self::Ordering::*;
110
110
use crate :: cell:: UnsafeCell ;
111
111
use crate :: fmt;
112
112
use crate :: intrinsics;
113
+ use crate :: mem:: align_of;
113
114
114
115
use crate :: hint:: spin_loop;
115
116
@@ -327,6 +328,27 @@ impl AtomicBool {
327
328
unsafe { & mut * ( self . v . get ( ) as * mut bool ) }
328
329
}
329
330
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
+
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,30 @@ 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
+ #[ 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
+
822
868
/// Consumes the atomic and returns the contained value.
823
869
///
824
870
/// This is safe because passing `self` by value guarantees that no other threads are
@@ -1121,6 +1167,7 @@ macro_rules! atomic_int {
1121
1167
$stable_nand: meta,
1122
1168
$const_stable: meta,
1123
1169
$stable_init_const: meta,
1170
+ $( from_mut: cfg( $from_mut_cfg: meta) , ) ?
1124
1171
$s_int_type: literal, $int_ref: expr,
1125
1172
$extra_feature: expr,
1126
1173
$min_fn: ident, $max_fn: ident,
@@ -1231,6 +1278,45 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
1231
1278
}
1232
1279
}
1233
1280
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
+
1234
1320
doc_comment! {
1235
1321
concat!( "Consumes the atomic and returns the contained value.
1236
1322
@@ -1989,6 +2075,7 @@ atomic_int! {
1989
2075
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
1990
2076
rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
1991
2077
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2078
+ from_mut: cfg( not( target_arch = "x86" ) ) ,
1992
2079
"i64" , "../../../std/primitive.i64.html" ,
1993
2080
"" ,
1994
2081
atomic_min, atomic_max,
@@ -2007,6 +2094,7 @@ atomic_int! {
2007
2094
stable( feature = "integer_atomics_stable" , since = "1.34.0" ) ,
2008
2095
rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
2009
2096
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2097
+ from_mut: cfg( not( target_arch = "x86" ) ) ,
2010
2098
"u64" , "../../../std/primitive.u64.html" ,
2011
2099
"" ,
2012
2100
atomic_umin, atomic_umax,
@@ -2025,6 +2113,7 @@ atomic_int! {
2025
2113
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2026
2114
rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
2027
2115
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2116
+ from_mut: cfg( not( target_arch = "x86_64" ) ) ,
2028
2117
"i128" , "../../../std/primitive.i128.html" ,
2029
2118
"#![feature(integer_atomics)]\n \n " ,
2030
2119
atomic_min, atomic_max,
@@ -2043,6 +2132,7 @@ atomic_int! {
2043
2132
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2044
2133
rustc_const_stable( feature = "const_integer_atomics" , since = "1.34.0" ) ,
2045
2134
unstable( feature = "integer_atomics" , issue = "32976" ) ,
2135
+ from_mut: cfg( not( target_arch = "x86_64" ) ) ,
2046
2136
"u128" , "../../../std/primitive.u128.html" ,
2047
2137
"#![feature(integer_atomics)]\n \n " ,
2048
2138
atomic_umin, atomic_umax,
0 commit comments