Search code examples
c++atomicstdatomiccompare-and-swap

Is there a way to have a version of std::atomic's compare_exchange_strong method that exchanges on inequality?


I have an atomic type where I need to atomically compare it with a value, and if the two values are not equal then exchange the value of the atomic.

Put another way, where compare_exchange_strong essentially does this operation atomically:

if (atomic_value == expected)
    atomic_value = desired;

...I'm looking for a way to do this:

if (atomic_value != expected)
    atomic_value = desired;

(Yes, I know compare_exchange_strong compares using bitwise equality, not the == operator. And I know the value of expected gets assigned when the comparison fails. This was just for illustration purposes. In my use case I don't need the value of the atomic regardless of the result of the comparison.)

Is there any way to do this without having to fall back on using a lock instead of std::atomic?


Solution

  • auto observed = atomic_value.load();
    for (;;)
    {
        if (observed == expected){
           break; // no exchange
        }
        if (atomic_value.compare_exchange_weak(observed, desired)) { 
           break; // successfully exchanged observed with desired
        }
    }
    

    Sure it is suboptimal on architectures where HW has LL/SC, as C++ does not expose it. With LL/SC can have arbitrary condition.