Skip to content

Commit 668225d

Browse files
committed
Revert "Revert adding Atomic::from_mut."
This reverts commit 5ef1db3.
1 parent 54fdf54 commit 668225d

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

library/core/src/sync/atomic.rs

+90
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ use self::Ordering::*;
110110
use crate::cell::UnsafeCell;
111111
use crate::fmt;
112112
use crate::intrinsics;
113+
use crate::mem::align_of;
113114

114115
use 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

Comments
 (0)