Home > Net >  what atomicity does compare_exchange_weak provide?
what atomicity does compare_exchange_weak provide?

Time:08-15

quote from https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange

bool compare_exchange_weak( T& expected, T desired, std::memory_order success, std::memory_order failure ) noexcept;

Atomically compares the object representation (until C 20)value representation (since C 20) of *this with that of expected, and if those are bitwise-equal, replaces the former with desired (performs read-modify-write operation). Otherwise, loads the actual value stored in *this into expected (performs load operation).

I'm having a hard time understanding the word Atomically mentioned above. Because expected and desired are all of type T, so read & write operation on these values are not atomic, if underlying atomic value and expected are not equal, Is the operation of loading *this to expected also atomic? or does Atomically only applies to operation related to underlying atomic value?

CodePudding user response:

Naively, the

compares the [representation] of *this with that of expected

and

replaces the former with desired

could be two separate operations that happen sequentially. One could imagine that it is possible that another thread writes a value after compares but before replaces into *this so that the second operation, replaces, overwrites the value that was just written by the other thread, which is now lost.

Atomically means that this cannot happen, i.e., that the two operations are actually only one uninterruptible operation.

CodePudding user response:

Because expected and desired are all of type T, so read & write operation on these values are not atomic

That's true. The load of expected (and the store, if it happens) is not an atomic operation. Therefore, if this call to compare_exchange_weak is potentially concurrent with any other operation that accesses expected, the program has a race condition (unless both operations are only reads). The load of desired is also not an atomic operation, although this doesn't matter because it's a local variable in the compare_exchange_weak function (no other thread can see it).

However, the operation on *this is atomic. This means that it will not race with any other potentially concurrent atomic operation on *this; if there are two potentially concurrent atomic operations on *this, the behaviour will be as if one thread or the other "gets there first", without causing any undefined behaviour. Furthermore, it will be either an atomic read-modify-write operation (on success) or an atomic load operation (on failure). An atomic read-modify-write operation has the additional constraint that the entry that it creates in the atomic variable's modification order immediately follows the entry from which the read took its value (no other modifications can "intervene").

  • Related