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?
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 T
s.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With