Skip to content

Commit aaa0334

Browse files
authored
Rollup merge of rust-lang#74532 - fusion-engineering-forks:atomic-from-mut, r=KodrAus
Add Atomic*::from_mut. The atomic equivalent of [`Cell::from_mut`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#method.from_mut).
2 parents 17d3277 + 3be40b2 commit aaa0334

File tree

1 file changed

+97
-1
lines changed

1 file changed

+97
-1
lines changed

library/core/src/sync/atomic.rs

+97-1
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
@@ -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::<AtomicPtr<()>>() - align_of::<*mut ()>()];
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")]
11081160
macro_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,
@@ -2020,6 +2114,7 @@ atomic_int! {
20202114
unstable(feature = "integer_atomics", issue = "32976"),
20212115
rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
20222116
unstable(feature = "integer_atomics", issue = "32976"),
2117+
from_mut: cfg(not(target_arch = "x86_64")),
20232118
"i128", "../../../std/primitive.i128.html",
20242119
"#![feature(integer_atomics)]\n\n",
20252120
atomic_min, atomic_max,
@@ -2038,6 +2133,7 @@ atomic_int! {
20382133
unstable(feature = "integer_atomics", issue = "32976"),
20392134
rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
20402135
unstable(feature = "integer_atomics", issue = "32976"),
2136+
from_mut: cfg(not(target_arch = "x86_64")),
20412137
"u128", "../../../std/primitive.u128.html",
20422138
"#![feature(integer_atomics)]\n\n",
20432139
atomic_umin, atomic_umax,

0 commit comments

Comments
 (0)