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));