Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C++11 have an std::atomic<T>::add_and_fetch method?

Tags:

c++

c++11

The C++11 standard includes the wonderful std::atomic<T>, which has member functions like this one:

integral fetch_add(integral, memory_order = memory_order_seq_cst);

However, it seems to be lacking in an add_fetch method. tbb::atomic<T> overloads the += operator to behave like add_and_fetch:

 value_type operator+=( D addend ) {
     return fetch_and_add(addend)+addend;
 }

Through empirical observation, std::atomic<T> behaves the same way, but I cannot find where it says so in the standard or if that is just my STL implementation. Is this behavior guaranteed by the standard?

like image 491
Travis Gockel Avatar asked Jan 25 '12 00:01

Travis Gockel


People also ask

What is std :: atomic in C++?

std::atomic<> wraps operations that, in pre-C++ 11 times, had to be performed using (for example) interlocked functions with MSVC or atomic bultins in case of GCC. Also, std::atomic<> gives you more control by allowing various memory orders that specify synchronization and ordering constraints.

Is STD atomic thread safe?

Yes, it would be threadsafe. Assuming of course there are no bugs in the std::atomic implementation - but it's not usually hard to get right. This is exactly what std::atomic is meant to do.

Is STD atomic copyable?

std::atomic is neither copyable nor movable. The compatibility macro _Atomic is provided in <stdatomic.

What is Fetch_add Atomic?

atomic::fetch_add (C++11)Atomically adds a value to an existing value that is stored in an atomic object. Memory is affected according to the value of order .


3 Answers

You're right that it doesn't actually provide that functionality but that's because it isn't needed. It can be emulated with the operations already there.

atomic_fetch_add is an atomic operation that fetches the current value then adds something. That "something" is totally under your control and is not changed by atomic_fetch_add.

The standard guarantees that:

  1. The old value is returned; and
  2. The value is added.

You can then simply add the value yourself to what was returned, and you have the current value as of the time the atomic operation was done. So basically:

def atomic_add_fetch (item, addendum):
    return atomic_fetch_add (item, addendum) + addendum

is the pseudo-code for an atomic_add_fetch operation.

like image 55
paxdiablo Avatar answered Sep 26 '22 13:09

paxdiablo


std::atomic<T> if T is an integral type, has a member operator+= which does the same thing. It is described, along with all other atomic compound assignment operators in §29.6.5/30-32

C A::operator op=(M operand) volatile noexcept;

C A::operator op=(M operand) noexcept;

Effects: fetch_key(operand)

Returns: fetch_key(operand) op operand

like image 34
Cubbi Avatar answered Sep 26 '22 13:09

Cubbi


However, it seems to be lacking in an add_fetch method.

Why would it need one? add_fetch would be this:

return atomic_value.fetch_add(number) + number;

Yes, it technically requires an extra addition. But that's pretty minor.

In any case, there is no add_fetch in the standard. There's just fetch_add, which returns the original value.

like image 23
Nicol Bolas Avatar answered Sep 22 '22 13:09

Nicol Bolas