Do I need to qualify updateAvailable as volatile ?
Since volatile does not correlate with the thread model in C ++, you should use atomatics to ensure strict confirmation of your program:
In C++11 or newer, the preferred way is to use atomic<bool> with memory_order_relaxed store / load:
atomic<bool> updateAvailable; //Writer .... updateAvailable.store(true, std::memory_order_relaxed); //set (under mutex locked) // Reader if(updateAvailable.load(std::memory_order_relaxed)) // check { ... updateAvailable.store(false, std::memory_order_relaxed); // clear (under mutex locked) .... }
gcc, since 4.7 supports similar functionality with atomic built-in .
As with gcc 4.6, it seems that there is no strictly confirming way to avoid fencing when the updateAvailable variable is updateAvailable . In fact, memory sampling is usually much faster than 10-100 m. Thus, you can use your own atomic built-in functions :
int updateAvailable = 0; //Writer ... __sync_fetch_and_or(&updateAvailable, 1); // set to non-zero .... //Reader if(__sync_fetch_and_and(&updateAvailable, 1)) // check, but never change { ... __sync_fetch_and_and(&updateAvailable, 0); // clear ... }
Is data sequence safe?
Yes, it is safe. Your reason is absolutely correct:
the shared resource is never affected / read on the fast read path.
This is NOT a double check lock!
This is explicitly stated in the question itself.
In the case where updateAvailable is false, the Reader thread uses the myDataCache variable, which is local to the thread (other threads do not use it). In a double-check locking scheme, all threads use the shared object directly.
Why no fences / memory barriers are needed here
The only variable available at the same time is updateAvailable . The myData variable is accessed using mutex protection, which provides all the necessary fences. myDataCache is local to the Reader thread.
When the read stream sees the updateAvailable variable as false, it uses the myDataCache variable, which is changed by the stream itself . Software warranties guarantee the correct visibility of changes in this case.
Regarding guaranteed visibility for the updateAvailable variable, the C ++ 11 standard provides such guarantees for the atomic variable, even without fences. 29.3 p13 says:
Implementations should make nuclear storage visible to atomic loads within a reasonable amount of time.
Jonathan Wackel has confirmed that this paragraph applies even to memory_order_relaxed to access chat .