Reputation: 19218
InterlockedCompareExchange
in Windows, as well as __sync_val_compare_and_swap
in gcc take pointers, and so I can pass in any address e.g. pointing into a shared memory block into those functions.
For non-x86 architectures, I might have to ensure memory alignment for correctness, and for x86 (and maybe others), I might want to ensure cache-line alignment for performance, although correctness should not be an issue (-> x86 LOCK
prefix).
Trying to get rid of some platform-dependent stuff in my code (Windows VC++ vs. GCC), I took a look at C++11's atomic_compare_exchange_weak
and friends. But they all work on a variable of type std::atomic<T>*
.
Is there a way to use arbitrary pointers with C++11's atomic functions? It doesn't look like a simple cast to std::atomic is gonna solve this.
Upvotes: 5
Views: 1587
Reputation: 42554
Short answer: they can't. This is necessary for portability of the language since C++ does not want to require that every platform to have lock-free support for a specific set of data sizes. Using std::atomic<T>
makes it easy for the library to transparently provide lock-free atomicity for some T
s and use a lock for others.
On the bright side, replacing T
with atomic<T>
in your codebase provides documentation of exactly what objects are used for synchronization, and provides protection against accidental non-atomic access to those objects.
Long answer: reinterpret_cast<std::atomic<decltype(t)>&>(t).store(value)
may actually work on some implementations during the right phase of the moon, but it's the purest evil.
Upvotes: 3