Description
RFC: rust-lang/rfcs#1543
Tracking issue: #32976
Documentation: https://doc.rust-lang.org/nightly/std/sync/atomic/
This issue is a proposal to stabilize the integer_atomics
feature as-is on nightly, modulo some documentation updates. Specifically, for each atomic type, this is proposed:
impl AtomicU8 {
pub const fn new(x: u8) -> AtomicU8;
pub fn get_mut(&mut self) -> &mut u8;
pub fn into_inner(self) -> u8;
pub fn load(&self, Ordering) -> u8;
pub fn store(&self, Ordering) -> u8;
pub fn swap(&self, val: u8, Ordering) -> u8;
pub fn compare_and_swap(&self, u8, u8, Ordering) -> u8;
pub fn compare_exchange(&self, u8, u8, Ordering, Ordering) -> Result<u8, u8>;
pub fn compare_exchange_weak(&self, u8, u8, Ordering, Ordering) -> Result<u8, u8>;
pub fn fetch_add(&self, u8, Ordering) -> u8;
pub fn fetch_sub(&self, u8, Ordering) -> u8;
pub fn fetch_and(&self, u8, Ordering) -> u8;
pub fn fetch_nand(&self, u8, Ordering) -> u8;
pub fn fetch_or(&self, u8, Ordering) -> u8;
pub fn fetch_xor(&self, u8, Ordering) -> u8;
}
Portability
One of the main points on the RFC and tracking issue is the portability of these types. @alexcrichton has compiled this table of known platform support, and the conclusions we've drawn with the libs team are:
- The
AtomicUsize
type is already "sketchily" supported. It's not present on armv5te (non-linux) and has a stripped down API on thumv6m - LLVM emulates small-size atomics with larger atomics (aka 1 byte atomics with 4 byte atomics) on platforms like MIPS. We're unclear on whether it's even possible to safely define these same operations on crates.io, as LLVM might deduce it's undefined behavior. It's sound, however, for LLVM's codegen backend to implement atomics like this.
- AtomicU32 and below are basically universally supported across all platforms that have any atomics at all.
- AtomicU64 actually has a good showing for support as well, except on mips/powerpc platforms.
It's proposed in this stabilization that we stabilize all APIs as-is, knowing that these apis are in a "portable location" yet are not as maximally portable as, say, Add for u8
. It's intended that platforms which don't support these types simply won't provide the types, as they do today. For example armv5te will continue to have none of these types. (for those following these issues, **it's not proposed that target_has_atomic
is stabilized as part of this proposal).
While this is a departure from the norms of the rest of the standard library, it's hopefully the most pragmatic decision here.
What about u128?
Some very recent (aka 20 minutes before this issue was opened) shows that AtomicU128
can be supported on x86_64 with the LLVM cx16
feature activated and aarch64 platforms. All other platforms look to require intrinsics one way or another. This proposal doesn't propose stabilizing these just yet, but the thinking is that a stable/safe std::arch::aarch64::AtomicU128
could be provided while a stable/unsafe std::arch::x86_64::AtomicU128
could be provided documenting the requirement of the target feature (exact name of the target feature TBD)
TODO checklist before stabilization:
- FCP
- Update documentation to reflect that AtomicU8/16/etc may be implemented in terms of 4-byte atomics
- Update documentation to reflect that these types are not maximally portable. Architectures that want to be supported should be tested. MIPS and PowerPC do not support AtomicU64, and "more esoteric" platforms like armv5te, thumv6m, etc, have little-to-no support.