Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there one `Atomic*` type for many primitive type instead of a generic `Atomic<T>`?

Tags:

atomic

rust

Looking at the std::sync::atomic module, one can see a bunch of different Atomic* types, like AtomicU32, AtomicI16 and more. Why is that?

Rust has generics and – as I see it – it would be possible to add a generic Atomic<T> where T is bounded by some trait defined in the module (in Java-ish naming: Atomicable). That trait would be implemented by the types that could be handled in an atomic fashion and users could just use Atomic<u32> instead of AtomicU32.

Why isn't there a generic Atomic<T>? Why have a bunch of different types instead?

like image 637
Lukas Kalbertodt Avatar asked Jul 17 '19 12:07

Lukas Kalbertodt


1 Answers

The purpose of having an AtomicU8 (for example) is using the underlying hardware to perform atomic instructions, e.g. on x86 the CMPXCHG instruction.

The original RFC #1505 suggested a Atomic<T> type. One of the main concern was, that people would use T in an unintended way, e.g. using Atomic<[u8; 32]> which would not be possible to support, because of the lack of hardware that support those.
A fallback/workaround by using a Mutex was proposed, but it felt like cheating, because the compiler would behave differently for different Ts.

It was finally closed in favor of RFC #1543 which introduced the Atomic{I,U}{8,16,32,64} types we know today.

It was then implemented in PR #33048 and stabilized in PR #56753 which is Rust 1.34.0.

To ensure, that the underlying hardware really supports the atomic operations the types are having a cfg attribute, e.g. for AtomicI8 it is #[cfg(target_has_atomic = "8")], for AtomicI16 it is #[cfg(target_has_atomic = "16")] etcetera.

like image 179
hellow Avatar answered Oct 11 '22 19:10

hellow