Search code examples
c++multithreadingthread-safetycompare-and-swapstdatomic

C++ atomics memory ordering for some specific use case


I'm in the next situation where I use a atomic<uint64_t> as a counter and increment it from 5 or more threads and use the value before increment to take some decision.

atomic<uint64_t> global_counter;

void thread_funtion(){
    uint64_t local_counter = global_counter.fetch_add(1,std::memory_order_relaxed);
    if(local_counter == 24)
       do_somthing(local_counter);
}

thread_funtion() will be executed by 5 different threads. Once I got the local_counter my code doesn't care anymore if the global_counter changes again while thread_funtion() is running (the business logic is in such a way that I only need have a unique incrementing value per thread_function() call).

Is std::memory_order_relaxed safe to be used in this case ?


Solution

  • atomic<...>::fetch_add(..., std::memory_order_relaxed) guarantees the atomic execution, but nothing more.

    But even with memory_order_relaxed, there will be one, and only one thread calling do_something(). Since this fetch_add is the only operation on global_counter, and it is executed atomically, the value 24 must be reached exactly once. But there is no guarantee which thread it will be.