Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ increment std::atomic_int if nonzero

Tags:

c++

c++11

atomic

I'm implementing a pointer / weak pointer mechanism using std::atomics for the reference counter (like this). For converting a weak pointer to a strong one I need to atomically

  • check if the strong reference counter is nonzero
  • if so, increment it
  • know whether something has changed.

Is there a way to do this using std::atomic_int? I think it has to be possible using one of the compare_exchange, but I can't figure it out.

like image 871
lucas clemente Avatar asked Dec 19 '12 10:12

lucas clemente


2 Answers

Given the definition std::atomic<int> ref_count;

int previous = ref_count.load();
for (;;)
{
    if (previous == 0)
        break;
    if (ref_count.compare_exchange_weak(previous, previous + 1))
        break;
}

previous will hold the previous value. Note that compare_exchange_weak will update previous if it fails.

like image 64
ymett Avatar answered Oct 20 '22 03:10

ymett


This should do it:

bool increment_if_non_zero(std::atomic<int>& i) {
    int expected = i.load();
    int to_be_loaded = expected;

    do {
        if(expected == 0) {
            to_be_loaded = expected;
        }
        else {
            to_be_loaded = expected + 1;
        }
    } while(!i.compare_exchange_weak(expected, to_be_loaded));

    return expected;
}
like image 22
Stephan Dollberg Avatar answered Oct 20 '22 03:10

Stephan Dollberg