InterlockedExchangeAdd Function

The InterlockedExchangeAdd function atomically adds a value to a specified variable and returns the original value of that variable.

LONG InterlockedExchangeAdd(
  [in, out]  LONG volatile *Addend,
  [in]       LONG Increment
);
                

Parameters

Parameter Type Description
Addend LONG volatile * A pointer to a 32-bit signed integer to be modified. The value is updated atomically.
Increment LONG The value to be added to the variable pointed to by Addend.

Return Value

The function returns the original value of the 32-bit integer pointed to by Addend before the addition occurred.

Remarks

The InterlockedExchangeAdd function provides a simple way to increment or decrement a variable in a multithreaded environment without race conditions. It guarantees that the read of the original value and the subsequent addition are performed as a single, uninterruptible operation.

This function is typically used for scenarios like maintaining counters, resource allocation tracking, or other operations where multiple threads might need to modify a shared integer value concurrently.

The volatile keyword is crucial here, ensuring that the compiler does not optimize away reads or writes to this variable, as its value can change unexpectedly by other threads.

The underlying hardware instruction for this operation is highly optimized, making it an efficient choice for atomic integer operations.

Example

The following example demonstrates how to use InterlockedExchangeAdd to safely increment a shared counter from multiple threads.


#include <windows.h>
#include <iostream>
#include <vector>
#include <thread>

volatile LONG sharedCounter = 0;
const int NUM_THREADS = 10;
const int INCREMENTS_PER_THREAD = 1000;

void IncrementCounter() {
    for (int i = 0; i < INCREMENTS_PER_THREAD; ++i) {
        InterlockedExchangeAdd(&sharedCounter, 1);
    }
}

int main() {
    std::vector<std::thread> threads;

    for (int i = 0; i < NUM_THREADS; ++i) {
        threads.push_back(std::thread(IncrementCounter));
    }

    for (auto& t : threads) {
        t.join();
    }

    std::cout << "Final counter value: " << sharedCounter << std::endl; // Should be NUM_THREADS * INCREMENTS_PER_THREAD
    return 0;
}