C++11 atomic memory ordering – is this a correct usage of relaxed (release-consume) ordering?

Why are you loading the old flags value twice in your CAS loops? The first time is by flags.load(), and the second by the compare_exchange_weak(), which the standard specifies on CAS failure will load the previous value into the first argument, which in this case is flagsNow.

According to http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange, “Otherwise, loads the actual value stored in *this into expected (performs load operation).” So what your loop is doing is that on failure, compare_exchange_weak() reloads flagsNow, then the loop repeats, and the first statement loads it once again, immediately after the load by compare_exchange_weak(). It seems to me your loop ought to instead have the load pulled outside the loop. For example, newSnap() would be:

uint_fast8_t flagsNow(flags.load(std::memory_order_consume));
do
{
    if( !isNewWrite(flagsNow)) return false; // nothing new, no need to swap
} while(!flags.compare_exchange_weak(flagsNow, swapSnapWithClean(flagsNow), memory_order_release, memory_order_consume));

and flipWriter():

uint_fast8_t flagsNow(flags.load(std::memory_order_consume));
while(!flags.compare_exchange_weak(flagsNow, newWriteSwapCleanWithDirty(flagsNow), memory_order_release, memory_order_consume));

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)