Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Atomic<T> type alias #130543

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
#![feature(extend_one_unchecked)]
#![feature(fmt_internals)]
#![feature(fn_traits)]
#![feature(generic_atomic)]
#![feature(hasher_prefixfree_extras)]
#![feature(inplace_iteration)]
#![feature(iter_advance_by)]
Expand Down
10 changes: 5 additions & 5 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use core::pin::{Pin, PinCoerceUnsized};
use core::ptr::{self, NonNull};
#[cfg(not(no_global_oom_handling))]
use core::slice::from_raw_parts_mut;
use core::sync::atomic;
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use core::sync::atomic::{self, Atomic};
use core::{borrow, fmt, hint};

#[cfg(not(no_global_oom_handling))]
Expand Down Expand Up @@ -346,12 +346,12 @@ impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
// inner types.
#[repr(C)]
struct ArcInner<T: ?Sized> {
strong: atomic::AtomicUsize,
strong: Atomic<usize>,

// the value usize::MAX acts as a sentinel for temporarily "locking" the
// ability to upgrade weak pointers or downgrade strong ones; this is used
// to avoid races in `make_mut` and `get_mut`.
weak: atomic::AtomicUsize,
weak: Atomic<usize>,

data: T,
}
Expand Down Expand Up @@ -2706,8 +2706,8 @@ impl<T, A: Allocator> Weak<T, A> {
/// Helper type to allow accessing the reference counts without
/// making any assertions about the data field.
struct WeakInner<'a> {
weak: &'a atomic::AtomicUsize,
strong: &'a atomic::AtomicUsize,
weak: &'a Atomic<usize>,
strong: &'a Atomic<usize>,
}

impl<T: ?Sized> Weak<T> {
Expand Down
100 changes: 97 additions & 3 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,100 @@ use crate::cell::UnsafeCell;
use crate::hint::spin_loop;
use crate::{fmt, intrinsics};

trait Sealed {}

/// A marker trait for primitive types which can be modified atomically.
///
/// This is an implementation detail for <code>[Atomic]\<T></code> which may disappear or be replaced at any time.
///
/// # Safety
///
/// Types implementing this trait must be primitives that can be modified atomically.
///
/// The associated `Self::AtomicInner` type must have the same size and bit validity as `Self`,
/// but may have a higher alignment requirement, so the following `transmute`s are sound:
///
/// - `&mut Self::AtomicInner` as `&mut Self`
/// - `Self` as `Self::AtomicInner` or the reverse
#[unstable(
feature = "atomic_internals",
reason = "implementation detail which may disappear or be replaced at any time",
issue = "none"
)]
#[allow(private_bounds)]
pub unsafe trait AtomicPrimitive: Sized + Copy + Sealed {
#[doc(hidden)]
type AtomicInner: Sized;
}

macro impl_atomic_primitive(
$Atom:ident $(<$T:ident>)? ($Primitive:ty),
size($size:literal),
align($align:literal) $(,)?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI the align is given to impl_atomic_primitive! because while it isn't actually used in this form, it's needed for the form where Atomic<T> is the struct definition. So it'll make the next diff a little cleaner (and here is kinda just residual from paring this back to just do an alias initially).

) {
impl $(<$T>)? Sealed for $Primitive {}

#[unstable(
feature = "atomic_internals",
reason = "implementation detail which may disappear or be replaced at any time",
issue = "none"
)]
#[cfg(target_has_atomic_load_store = $size)]
unsafe impl $(<$T>)? AtomicPrimitive for $Primitive {
type AtomicInner = $Atom $(<$T>)?;
}
}

impl_atomic_primitive!(AtomicBool(bool), size("8"), align(1));
impl_atomic_primitive!(AtomicI8(i8), size("8"), align(1));
impl_atomic_primitive!(AtomicU8(u8), size("8"), align(1));
impl_atomic_primitive!(AtomicI16(i16), size("16"), align(2));
impl_atomic_primitive!(AtomicU16(u16), size("16"), align(2));
impl_atomic_primitive!(AtomicI32(i32), size("32"), align(4));
impl_atomic_primitive!(AtomicU32(u32), size("32"), align(4));
impl_atomic_primitive!(AtomicI64(i64), size("64"), align(8));
impl_atomic_primitive!(AtomicU64(u64), size("64"), align(8));
impl_atomic_primitive!(AtomicI128(i128), size("128"), align(16));
impl_atomic_primitive!(AtomicU128(u128), size("128"), align(16));

#[cfg(target_pointer_width = "16")]
impl_atomic_primitive!(AtomicIsize(isize), size("ptr"), align(2));
#[cfg(target_pointer_width = "32")]
impl_atomic_primitive!(AtomicIsize(isize), size("ptr"), align(4));
#[cfg(target_pointer_width = "64")]
impl_atomic_primitive!(AtomicIsize(isize), size("ptr"), align(8));

#[cfg(target_pointer_width = "16")]
impl_atomic_primitive!(AtomicUsize(usize), size("ptr"), align(2));
#[cfg(target_pointer_width = "32")]
impl_atomic_primitive!(AtomicUsize(usize), size("ptr"), align(4));
#[cfg(target_pointer_width = "64")]
impl_atomic_primitive!(AtomicUsize(usize), size("ptr"), align(8));

#[cfg(target_pointer_width = "16")]
impl_atomic_primitive!(AtomicPtr<T>(*mut T), size("ptr"), align(2));
#[cfg(target_pointer_width = "32")]
impl_atomic_primitive!(AtomicPtr<T>(*mut T), size("ptr"), align(4));
#[cfg(target_pointer_width = "64")]
impl_atomic_primitive!(AtomicPtr<T>(*mut T), size("ptr"), align(8));

/// A memory location which can be safely modified from multiple threads.
///
/// This has the same size and bit validity as the underlying type `T`. However,
/// the alignment of this type is always equal to its size, even on targets where
/// `T` has alignment less than its size.
///
/// For more about the differences between atomic types and non-atomic types as
/// well as information about the portability of this type, please see the
/// [module-level documentation].
///
/// **Note:** This type is only available on platforms that support atomic loads
/// and stores of `T`.
///
/// [module-level documentation]: crate::sync::atomic
#[unstable(feature = "generic_atomic", issue = "130539")]
pub type Atomic<T> = <T as AtomicPrimitive>::AtomicInner;

// Some architectures don't have byte-sized atomics, which results in LLVM
// emulating them using a LL/SC loop. However for AtomicBool we can take
// advantage of the fact that it only ever contains 0 or 1 and use atomic OR/AND
Expand Down Expand Up @@ -388,7 +482,7 @@ pub enum Ordering {
note = "the `new` function is now preferred",
suggestion = "AtomicBool::new(false)"
)]
pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
pub const ATOMIC_BOOL_INIT: Atomic<bool> = AtomicBool::new(false);
CAD97 marked this conversation as resolved.
Show resolved Hide resolved

#[cfg(target_has_atomic_load_store = "8")]
impl AtomicBool {
Expand Down Expand Up @@ -3253,7 +3347,7 @@ macro_rules! atomic_int_ptr_sized {
note = "the `new` function is now preferred",
suggestion = "AtomicIsize::new(0)",
)]
pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0);
pub const ATOMIC_ISIZE_INIT: Atomic<isize> = AtomicIsize::new(0);
CAD97 marked this conversation as resolved.
Show resolved Hide resolved

/// An [`AtomicUsize`] initialized to `0`.
#[cfg(target_pointer_width = $target_pointer_width)]
Expand All @@ -3263,7 +3357,7 @@ macro_rules! atomic_int_ptr_sized {
note = "the `new` function is now preferred",
suggestion = "AtomicUsize::new(0)",
)]
pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0);
pub const ATOMIC_USIZE_INIT: Atomic<usize> = AtomicUsize::new(0);
CAD97 marked this conversation as resolved.
Show resolved Hide resolved
)* };
}

Expand Down
4 changes: 2 additions & 2 deletions library/std/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
#![stable(feature = "alloc_module", since = "1.28.0")]

use core::ptr::NonNull;
use core::sync::atomic::{AtomicPtr, Ordering};
use core::sync::atomic::{Atomic, AtomicPtr, Ordering};
use core::{hint, mem, ptr};

#[stable(feature = "alloc_module", since = "1.28.0")]
Expand Down Expand Up @@ -287,7 +287,7 @@ unsafe impl Allocator for System {
}
}

static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
static HOOK: Atomic<*mut ()> = AtomicPtr::new(ptr::null_mut());

/// Registers a custom allocation error hook, replacing any that was previously registered.
///
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ mod tests;
use crate::backtrace_rs::{self, BytesOrWideString};
use crate::ffi::c_void;
use crate::panic::UnwindSafe;
use crate::sync::atomic::AtomicU8;
use crate::sync::atomic::Ordering::Relaxed;
use crate::sync::atomic::{Atomic, AtomicU8};
use crate::sync::LazyLock;
use crate::sys::backtrace::{lock, output_filename, set_image_base};
use crate::{env, fmt};
Expand Down Expand Up @@ -254,7 +254,7 @@ impl Backtrace {
// Cache the result of reading the environment variables to make
// backtrace captures speedy, because otherwise reading environment
// variables every time can be somewhat slow.
static ENABLED: AtomicU8 = AtomicU8::new(0);
static ENABLED: Atomic<u8> = AtomicU8::new(0);
match ENABLED.load(Relaxed) {
0 => {}
1 => return false,
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::io::{
self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines, SpecReadByte,
};
use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::atomic::{Atomic, AtomicBool, Ordering};
use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantLock, ReentrantLockGuard};
use crate::sys::stdio;
use crate::thread::AccessError;
Expand All @@ -37,7 +37,7 @@ thread_local! {
/// have a consistent order between set_output_capture and print_to *within
/// the same thread*. Within the same thread, things always have a perfectly
/// consistent order. So Ordering::Relaxed is fine.
static OUTPUT_CAPTURE_USED: AtomicBool = AtomicBool::new(false);
static OUTPUT_CAPTURE_USED: Atomic<bool> = AtomicBool::new(false);

/// A handle to a raw instance of the standard input stream of this process.
///
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@
#![feature(float_minimum_maximum)]
#![feature(float_next_up_down)]
#![feature(fmt_internals)]
#![feature(generic_atomic)]
#![feature(hasher_prefixfree_extras)]
#![feature(hashmap_internals)]
#![feature(ip)]
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/os/uefi/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

use crate::ffi::c_void;
use crate::ptr::NonNull;
use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
use crate::sync::atomic::{Atomic, AtomicBool, AtomicPtr, Ordering};

static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
static IMAGE_HANDLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
static SYSTEM_TABLE: Atomic<*mut c_void> = AtomicPtr::new(crate::ptr::null_mut());
static IMAGE_HANDLE: Atomic<*mut c_void> = AtomicPtr::new(crate::ptr::null_mut());
// Flag to check if BootServices are still valid.
// Start with assuming that they are not available
static BOOT_SERVICES_FLAG: AtomicBool = AtomicBool::new(false);
static BOOT_SERVICES_FLAG: Atomic<bool> = AtomicBool::new(false);

/// Initializes the global System Table and Image Handle pointers.
///
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/os/xous/services.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::sync::atomic::{AtomicU32, Ordering};
use core::sync::atomic::{Atomic, AtomicU32, Ordering};

use crate::os::xous::ffi::Connection;

Expand Down Expand Up @@ -106,7 +106,7 @@ pub fn try_connect(name: &str) -> Option<Connection> {
ns::try_connect_with_name(name)
}

static NAME_SERVER_CONNECTION: AtomicU32 = AtomicU32::new(0);
static NAME_SERVER_CONNECTION: Atomic<u32> = AtomicU32::new(0);

/// Returns a `Connection` to the name server. If the name server has not been started,
/// then this call will block until the name server has been started. The `Connection`
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/os/xous/services/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Into<usize> for DnsLendMut {
/// Returns a `Connection` to the DNS lookup server. This server is used for
/// querying domain name values.
pub(crate) fn dns_server() -> Connection {
static DNS_CONNECTION: AtomicU32 = AtomicU32::new(0);
static DNS_CONNECTION: Atomic<u32> = AtomicU32::new(0);
let cid = DNS_CONNECTION.load(Ordering::Relaxed);
if cid != 0 {
return cid.into();
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/os/xous/services/log.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::sync::atomic::{AtomicU32, Ordering};
use core::sync::atomic::{Atomic, AtomicU32, Ordering};

use crate::os::xous::ffi::Connection;

Expand Down Expand Up @@ -64,7 +64,7 @@ impl Into<usize> for LogLend {
/// running. It is safe to call this multiple times, because the address is
/// shared among all threads in a process.
pub(crate) fn log_server() -> Connection {
static LOG_SERVER_CONNECTION: AtomicU32 = AtomicU32::new(0);
static LOG_SERVER_CONNECTION: Atomic<u32> = AtomicU32::new(0);

let cid = LOG_SERVER_CONNECTION.load(Ordering::Relaxed);
if cid != 0 {
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/os/xous/services/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<'a> Into<[usize; 5]> for NetBlockingScalar {
/// Returns a `Connection` to the Network server. This server provides all
/// OS-level networking functions.
pub(crate) fn net_server() -> Connection {
static NET_CONNECTION: AtomicU32 = AtomicU32::new(0);
static NET_CONNECTION: Atomic<u32> = AtomicU32::new(0);
let cid = NET_CONNECTION.load(Ordering::Relaxed);
if cid != 0 {
return cid.into();
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/os/xous/services/systime.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::sync::atomic::{AtomicU32, Ordering};
use core::sync::atomic::{Atomic, AtomicU32, Ordering};

use crate::os::xous::ffi::{connect, Connection};

Expand All @@ -17,7 +17,7 @@ impl Into<[usize; 5]> for SystimeScalar {
/// Returns a `Connection` to the systime server. This server is used for reporting the
/// realtime clock.
pub(crate) fn systime_server() -> Connection {
static SYSTIME_SERVER_CONNECTION: AtomicU32 = AtomicU32::new(0);
static SYSTIME_SERVER_CONNECTION: Atomic<u32> = AtomicU32::new(0);
let cid = SYSTIME_SERVER_CONNECTION.load(Ordering::Relaxed);
if cid != 0 {
return cid.into();
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/os/xous/services/ticktimer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::sync::atomic::{AtomicU32, Ordering};
use core::sync::atomic::{Atomic, AtomicU32, Ordering};

use crate::os::xous::ffi::Connection;

Expand Down Expand Up @@ -31,7 +31,7 @@ impl Into<[usize; 5]> for TicktimerScalar {
/// Returns a `Connection` to the ticktimer server. This server is used for synchronization
/// primitives such as sleep, Mutex, and Condvar.
pub(crate) fn ticktimer_server() -> Connection {
static TICKTIMER_SERVER_CONNECTION: AtomicU32 = AtomicU32::new(0);
static TICKTIMER_SERVER_CONNECTION: Atomic<u32> = AtomicU32::new(0);
let cid = TICKTIMER_SERVER_CONNECTION.load(Ordering::Relaxed);
if cid != 0 {
return cid.into();
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![stable(feature = "std_panic", since = "1.9.0")]

use crate::any::Any;
use crate::sync::atomic::{AtomicU8, Ordering};
use crate::sync::atomic::{Atomic, AtomicU8, Ordering};
use crate::sync::{Condvar, Mutex, RwLock};
use crate::thread::Result;
use crate::{collections, fmt, panicking};
Expand Down Expand Up @@ -456,7 +456,7 @@ impl BacktraceStyle {
// that backtrace.
//
// Internally stores equivalent of an Option<BacktraceStyle>.
static SHOULD_CAPTURE: AtomicU8 = AtomicU8::new(0);
static SHOULD_CAPTURE: Atomic<u8> = AtomicU8::new(0);

/// Configures whether the default panic hook will capture and display a
/// backtrace.
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::any::Any;
use crate::io::try_set_output_capture;
use crate::mem::{self, ManuallyDrop};
use crate::panic::{BacktraceStyle, PanicHookInfo};
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::atomic::{Atomic, AtomicBool, Ordering};
use crate::sync::{PoisonError, RwLock};
use crate::sys::stdio::panic_output;
use crate::sys::{backtrace, dbg};
Expand Down Expand Up @@ -257,7 +257,7 @@ fn default_hook(info: &PanicHookInfo<'_>) {
let mut lock = backtrace::lock();
let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");

static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
static FIRST_PANIC: Atomic<bool> = AtomicBool::new(true);

match backtrace {
// SAFETY: we took out a lock just a second ago.
Expand Down Expand Up @@ -342,7 +342,7 @@ pub mod panic_count {
#[unstable(feature = "update_panic_count", issue = "none")]
pub mod panic_count {
use crate::cell::Cell;
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};

const ALWAYS_ABORT_FLAG: usize = 1 << (usize::BITS - 1);

Expand Down Expand Up @@ -384,7 +384,7 @@ pub mod panic_count {
//
// Stealing a bit is fine because it just amounts to assuming that each
// panicking thread consumes at least 2 bytes of address space.
static GLOBAL_PANIC_COUNT: AtomicUsize = AtomicUsize::new(0);
static GLOBAL_PANIC_COUNT: Atomic<usize> = AtomicUsize::new(0);

// Increases the global and local panic count, and returns whether an
// immediate abort is required.
Expand Down
Loading
Loading