Skip to content

Commit

Permalink
Auto merge of #115719 - tgross35:atomic-from-ptr, r=dtolnay
Browse files Browse the repository at this point in the history
Stabilize `atomic_from_ptr`

This stabilizes `atomic_from_ptr` and moves the const gate to `const_atomic_from_ptr`. Const stability is blocked on `const_mut_refs`.

Tracking issue:  #108652

Newly stable API:

```rust
// core::atomic

impl AtomicBool { pub unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool; }

impl<T> AtomicPtr<T> { pub unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T>; }

impl AtomicU8    { pub unsafe fn from_ptr<'a>(ptr: *mut u8)    -> &'a AtomicU8;    }
impl AtomicU16   { pub unsafe fn from_ptr<'a>(ptr: *mut u16)   -> &'a AtomicU16;   }
impl AtomicU32   { pub unsafe fn from_ptr<'a>(ptr: *mut u32)   -> &'a AtomicU32;   }
impl AtomicU64   { pub unsafe fn from_ptr<'a>(ptr: *mut u64)   -> &'a AtomicU64;   }
impl AtomicUsize { pub unsafe fn from_ptr<'a>(ptr: *mut usize) -> &'a AtomicUsize; }

impl AtomicI8    { pub unsafe fn from_ptr<'a>(ptr: *mut i8)    -> &'a AtomicI8;    }
impl AtomicI16   { pub unsafe fn from_ptr<'a>(ptr: *mut i16)   -> &'a AtomicI16;   }
impl AtomicI32   { pub unsafe fn from_ptr<'a>(ptr: *mut i32)   -> &'a AtomicI32;   }
impl AtomicI64   { pub unsafe fn from_ptr<'a>(ptr: *mut i64)   -> &'a AtomicI64;   }
impl AtomicIsize { pub unsafe fn from_ptr<'a>(ptr: *mut isize) -> &'a AtomicIsize; }
```
  • Loading branch information
bors committed Oct 14, 2023
2 parents 75a5dd0 + 227c844 commit 2a7c2df
Showing 1 changed file with 45 additions and 16 deletions.
61 changes: 45 additions & 16 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ impl AtomicBool {
/// # Examples
///
/// ```
/// #![feature(atomic_from_ptr, pointer_is_aligned)]
/// #![feature(pointer_is_aligned)]
/// use std::sync::atomic::{self, AtomicBool};
/// use std::mem::align_of;
///
Expand All @@ -346,13 +346,21 @@ impl AtomicBool {
///
/// # Safety
///
/// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can be bigger than `align_of::<bool>()`).
/// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can
/// be bigger than `align_of::<bool>()`).
/// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
/// * The value behind `ptr` must not be accessed through non-atomic operations for the whole lifetime `'a`.
/// * Non-atomic accesses to the value behind `ptr` must have a happens-before relationship
/// with atomic accesses via the returned value (or vice-versa).
/// * In other words, time periods where the value is accessed atomically may not overlap
/// with periods where the value is accessed non-atomically.
/// * This requirement is trivially satisfied if `ptr` is never used non-atomically for the
/// duration of lifetime `'a`. Most use cases should be able to follow this guideline.
/// * This requirement is also trivially satisfied if all accesses (atomic or not) are done
/// from the same thread.
///
/// [valid]: crate::ptr#safety
#[unstable(feature = "atomic_from_ptr", issue = "108652")]
#[rustc_const_unstable(feature = "atomic_from_ptr", issue = "108652")]
#[stable(feature = "atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")]
pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool {
// SAFETY: guaranteed by the caller
unsafe { &*ptr.cast() }
Expand Down Expand Up @@ -1113,7 +1121,7 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(atomic_from_ptr, pointer_is_aligned)]
/// #![feature(pointer_is_aligned)]
/// use std::sync::atomic::{self, AtomicPtr};
/// use std::mem::align_of;
///
Expand All @@ -1140,13 +1148,23 @@ impl<T> AtomicPtr<T> {
///
/// # Safety
///
/// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this can be bigger than `align_of::<*mut T>()`).
/// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
/// can be bigger than `align_of::<*mut T>()`).
/// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
/// * The value behind `ptr` must not be accessed through non-atomic operations for the whole lifetime `'a`.
/// * Non-atomic accesses to the value behind `ptr` must have a happens-before relationship
/// with atomic accesses via the returned value (or vice-versa).
/// * In other words, time periods where the value is accessed atomically may not overlap
/// with periods where the value is accessed non-atomically.
/// * This requirement is trivially satisfied if `ptr` is never used non-atomically for the
/// duration of lifetime `'a`. Most use cases should be able to follow this guideline.
/// * This requirement is also trivially satisfied if all accesses (atomic or not) are done
/// from the same thread.
/// * This method should not be used to create overlapping or mixed-size atomic accesses, as
/// these are not supported by the memory model.
///
/// [valid]: crate::ptr#safety
#[unstable(feature = "atomic_from_ptr", issue = "108652")]
#[rustc_const_unstable(feature = "atomic_from_ptr", issue = "108652")]
#[stable(feature = "atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")]
pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> {
// SAFETY: guaranteed by the caller
unsafe { &*ptr.cast() }
Expand Down Expand Up @@ -2083,7 +2101,7 @@ macro_rules! atomic_int {
/// # Examples
///
/// ```
/// #![feature(atomic_from_ptr, pointer_is_aligned)]
/// #![feature(pointer_is_aligned)]
#[doc = concat!($extra_feature, "use std::sync::atomic::{self, ", stringify!($atomic_type), "};")]
/// use std::mem::align_of;
///
Expand Down Expand Up @@ -2111,14 +2129,25 @@ macro_rules! atomic_int {
///
/// # Safety
///
/// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can be bigger than `align_of::<bool>()`).
#[doc = concat!(" * `ptr` must be aligned to `align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this can be bigger than `align_of::<", stringify!($int_type), ">()`).")]
#[doc = concat!(" * `ptr` must be aligned to \
`align_of::<", stringify!($atomic_type), ">()` (note that on some platforms this \
can be bigger than `align_of::<", stringify!($int_type), ">()`).")]
/// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
/// * The value behind `ptr` must not be accessed through non-atomic operations for the whole lifetime `'a`.
/// * Non-atomic accesses to the value behind `ptr` must have a happens-before
/// relationship with atomic accesses via the returned value (or vice-versa).
/// * In other words, time periods where the value is accessed atomically may not
/// overlap with periods where the value is accessed non-atomically.
/// * This requirement is trivially satisfied if `ptr` is never used non-atomically
/// for the duration of lifetime `'a`. Most use cases should be able to follow
/// this guideline.
/// * This requirement is also trivially satisfied if all accesses (atomic or not) are
/// done from the same thread.
/// * This method should not be used to create overlapping or mixed-size atomic
/// accesses, as these are not supported by the memory model.
///
/// [valid]: crate::ptr#safety
#[unstable(feature = "atomic_from_ptr", issue = "108652")]
#[rustc_const_unstable(feature = "atomic_from_ptr", issue = "108652")]
#[stable(feature = "atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_unstable(feature = "const_atomic_from_ptr", issue = "108652")]
pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type {
// SAFETY: guaranteed by the caller
unsafe { &*ptr.cast() }
Expand Down

0 comments on commit 2a7c2df

Please sign in to comment.