Even if is_lock_free() == false
, typically maybe, the atomicity of std::atomic can be guaranteed. Is that right?
I wander that there are computer environments or cases where the atomicity is not guaranteed, when is_lock_free() == false
.
CodePudding user response:
Non-lock-free atomics aren't address-free, so shared memory between two processes would mean they don't respect each other's lock. (Same for two virtual mappings of a page holding the same atomic object in the same process, unless the hash table of locks is only indexed on the low bits of the address, the offset-within-page, but that would probably be a bad design.)
ISO C doesn't define memory-mapping functions or processes, so the standard itself doesn't go into much detail other than saying lock-free atomics should be address-free (which makes them work in shared memory). That is the case on real-world implementations.
Otherwise it's always atomic. The usual implementation mechanism is simple: use the address to index a table of spinlocks or mutexes.
Of course, this assumes a program free of undefined behaviour, but so does everything else in C . Any UB anywhere during the execution of a C program means all guarantees of anything before or after that point are out the window.
In practice there aren't a lot of ways you could break atomicity of a non-lock-free std::atomic
, other than really obvious stuff like using memcpy
or a plain-uint64_t*
to access the object representation, instead of going through the std::atomic<uint64_t>
class.
Lock-free std::atomic is actually easier to break with UB, e.g. by dereferencing an atomic<T>*
that's not aligned to alignof(std::atomic<T>)
. On many ISAs that support unaligned loads/stores, that will run but not actually be atomic, because the C implementation was relying on hardware guarantees for atomicity of aligned loads and stores.