Search code examples
c++qtatomic

Atomic read with QAtomicInt/QAtomicPointer


How do I read the value of a QAtomicInt or QAtomicPointer atomically in Qt4, on all supported architectures? I don't care about memory ordering here, I just want to be sure that I won't read a partially old, partially new value if another thread is concurrently changing the value.

In Qt4, these classes only have cast operators for int or T*. There seems to be newer code (http://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/thread/qbasicatomic.h) which distinguishes between non-atomic load() and atomic loadAcquire(). C++11 atomics also have an atomic load() (http://en.cppreference.com/w/cpp/atomic/atomic/load). That's why I am worried that the methods provided by Qt4 are not safe enough.

I know fetchAndAddRelaxed(0) should work, but it looks like a hack and is probably not optimal in terms of performance.


Solution

  • Basically the answer is yes. Virtually all modern platforms allow at least 32-bit or 64-bit atomic loads/stores provided the variables are aligned. (Atomic used here in the sense that you will not load a "partial" value)

    Now the Qt documentation does not make it clear that their atomics provide this using the basic (what they call confusingly non-atomic) load() and store(). 'loadAcquire()' and especially `fetchAndAddRelaxed(0)' are more expensive than what you need - 'loadAcquire' being by far the cheapest of these 2.

    If I were you, I would simply use load() and store(). If you want more guarantee wrt to the Qt documentation, loadAcquire is the cheapest way and in architecture like x86 is like load().

    The best way would be to use the C++11 atomic with the relaxed memory model which is what you want.