I am doing a refactoring of widely used open source library and want to make it as robust as possible.
Currently, it uses atomic size_t
variables if it is supported but I wonder if it can miss some obscure platform which has, for example, 32 bit atomics while having 64 bit pointers.
I'm pretty sure all modern mainstream systems have lock-free pointer-width atomics, at least ones that run OSes like Linux.
8-bit platforms like AVR can mostly only load/store bytes, but pointers are 16 or 24 bit, so size_t
wouldn't be lock-free either. (But AVR systems are single-core, and even for single bytes you only get RMW atomicity by disabling interrupts.)
Only a segmented memory model or something would have pointers wider than size_t
. Flat memory models are nearly universal, where size_t
and uintptr_t
are the same size, and same width as pointers.
Many ISAs have lock-free atomic RMW for 2x pointer width, but not always efficient pure-load or pure-store for that width. (For example, x86-64 without AVX for the recently-documented guarantee of 128-bit atomicity only has lock cmpxchg16b
, which can be "abused" for pure load and pure store. But that dirties the cache line, and even faults on read-only memory. Which is party of why GCC since 7 doesn't inline 16-byte atomic load, store, or RMW, even with -mcx16
.)
The Rust docs (https://doc.rust-lang.org/stable/std/sync/atomic/index.html) discuss some older platforms like armv5te apparently only had atomic load/store, not atomic RMW like CAS or even swap/exchange. That required OS support, presumably disabling interrupts on a single-core CPU/MCU. Similarly for "thumbv6m". But that's a problem for AtomicUsize
as well as AtomicPtr
.