Search code examples
c++winapiatomicassignment-operator

Atomic Assignment Operator


I'm implementing a very light atomic wrapper as a learning exercise for primitive data types in C++ for Windows, and I have a few simple questions about implementing the assignment operator. Consider the two implementations below:

// Simple assignment
Atomic& Atomic::operator=(const Atomic& other)
{
    mValue = other.mValue;
    return *this;
}

// Interlocked assignment
Atomic& Atomic::operator=(const Atomic& other)
{
    _InterlockedExchange(&mValue, other.mValue);
    return *this;
}

Assume that mValue is the correct type and that the Atomic class has it as a member.

  1. Is _InterlockedExchange needed for a thread-safe assignment operator, or is the simple implementation enough to guarantee thread-safety?
  2. If the simple assignment is thread-safe, then is it even needed to implement the assignment operator for this class? The compiler default should suffice, no?
  3. If the simple assignment is thread-safe in Windows, is it also thread-safe in other platforms? Is the equivalent of _InterlockedExchange required to guarantee thread safety on other platforms?

Solution

  • if mValue is a primitive type (and at most 32 bits wide on a 32-bit CPU, at most 64 bits wide on a 64-bit CPU), and you're running on an x86 CPU (in 32 or 64 bit mode) and you don't manually misalign data, then memory reads/writes are guaranteed to be atomic.

    This does not, in itself, mean that the compiler won't reorder memory accesses or even optimize it out entirely, but the CPU does guarantee that any well-aligned read/write with data of those sizes will be atomic.

    However, note that I'm talking about atomicity, not thread safety, because "thread safety" depends on the context in which the code is used.