XLE
v0.02.0
|
Typedefs | |
typedef long | Value |
typedef int64 | Value64 |
This namespace provides low-level utility functions for atomic operations. Mostly this namespace wraps some low-level api providing the functionality required (this gives us flexibility to choose different low level api, and perhaps provide different solutions for different platforms).
Important note: Functions in the Interlocked namespace always return the previous value of the target! This differs from the Win32 API InterlockedAdd, etc!
Win32 InterlockedAdd(&target, addition) -> returns old "target" + addition Interlocked::InterlockedAdd(&target, addition) -> returns old "target"
This simple rule seems is more intuitive and consistant. Interlocked::Exchange and other functions also work in this same way – return the "old" value.
But it means that code previously used Win32 InterlockedAdd() must be change to suit this behaviour.
As an example, here is reference count Release() behaviour:
When using atomic functions, there are issues related to the ordering of instruction completion relative to other instructions. In certain cases, a thread can see an atomic value change in way that appears out-of-order relative to other memory changes.
This is particularly important for mutexes and threading control primitives. When a mutex is unlocked, it's normal to assume that memory writes to the object that mutex protects will be committed to memory. However, this isn't guaranteed unless there is a memory barrier to properly synchronize memory. Normally mutex implementations will take care of this. However it's worth noting when writing custom thread control (eg, a spin lock) that use these Interlocked methods.
For more information on this topic, see documentation on std::memory_order (part of the new C++ standard)
When using the Win32 intrinsic implementations of InterlockedExchange, etc, these automatically place a read/write barrier that effects the behaviour of the compiler, and possibly a memory barrier as well. See the MSVC documentation for _ReadWriteBarrier. The documentation is a little unclear about whether there is a runtime memory barrier (and on what platforms it takes effect).