Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare and increment an atomic variable

I want to know is it possible to perform comparison and increment of an atomic variable using a single atomic operation. This is what I have written so far(snippet code of a thread)

std::atomic<int> counter; //global variable

if(counter<25)
{
counter++;
}
else
{
     //send serial/socket data
}

I know that I am doing wrong since atomic variable counter is accessed two times(once for getting the data and other for increment). But this may cause a problem if another thread performs some update operation on 'counter' after getting the variable value and before increment. So I want to know is it possible to do both these operations in a single shot. Also I don't want to use mutex.

like image 336
Harry Avatar asked Oct 26 '25 03:10

Harry


1 Answers

In if(counter<25) counter++; there is a race condition between reading the counter and updating it (i.e. an atomic load followed by atomic load-modify-store).

It needs a compare-exchange loop to make sure the value read has not changed since. If it has changed, the operation needs to be retried.

Something like the following:

std::atomic<int> counter;

auto value = counter.load(std::memory_order_relaxed);
while(value < 25) {
    if(counter.compare_exchange_weak(value, value + 1, std::memory_order_release, std::memory_order_relaxed))
        break; // Succeeded incrementing counter.
    // compare_exchange_weak failed because counter has changed.
    // compare_exchange_weak reloaded value with the new value of counter.
    // Retry.
}
if(!(value < 25))
    // Failed to increment because counter is not less than 25.
like image 53
Maxim Egorushkin Avatar answered Oct 28 '25 17:10

Maxim Egorushkin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!