#include <QThread.h>
Modern processors have direct processor ops for handling atomic manipulation of an integer in multiprocessor systems (the very least a multiprocessor capable system needs is an atomic swap instruction). All synchronisation primitives (such as a semaphore or mutex) require atomic integer manipulation support in hardware.
There are a number of instances when using QMutex or other TnFOX synchronisation classes are overkill and inefficient eg; a thread-safe incrementing counter. In these cases, FXAtomicInt can provide substantially improved performance. Indeed, QMutex is implemented using it.
With modern compiler help, direct assembler is mostly avoided. On MSVC and GCC, compiler intrinsics are used to access processor-specific locking instructions. As GCC has very limited intrinsics in this area requiring a separate lock variable, on x86 or x64 direct assembler is used on that compiler - however, on other platforms the operation is simply more inefficient than if native instructions are used:
3400 Athlon64 uniprocessor on Apple MacOS X with GCC v4.0.1: FXAtomicInt QMutex GCC intrinsics: 9159606 2654350 Direct assembler: 47438330 7844367 (5.2x) (3x)
As of v0.85, the macro FX_SMPBUILD when defined causes the CPU to take exclusive control of the memory bus during the operation which is correct for SMP but overkill for uniprocessor systems. Setting makeSMPBuild to False in config.py will around double the FXAtomicInt performance. As an example of how expensive locked memory bus operations are, write a simple loop incrementing a FXAtomicInt and watch how slow your machine becomes!
As of v0.86, defining FXINLINE_MUTEX_IMPLEMENTATION defines this class inline to all code including QThread.h. This can cause substantial performance improvement at the cost of code size.
Public Member Functions | |
QMUTEX_INLINEP | FXAtomicInt (int i=0) throw () |
QMUTEX_INLINEP | FXAtomicInt (const FXAtomicInt &o) throw () |
QMUTEX_INLINEP FXAtomicInt & | operator= (const FXAtomicInt &o) throw () |
QMUTEX_INLINEP | operator int () const throw () |
QMUTEX_INLINEP int | operator= (int i) throw () |
QMUTEX_INLINEP int | operator++ (int) throw () |
QMUTEX_INLINEP int | operator++ () throw () |
QMUTEX_INLINEP int | fastinc () throw () |
QMUTEX_INLINEP int | operator+= (int i) throw () |
QMUTEX_INLINEP int | operator-- (int) throw () |
QMUTEX_INLINEP int | operator-- () throw () |
QMUTEX_INLINEP int | fastdec () throw () |
QMUTEX_INLINEP int | operator-= (int i) throw () |
QMUTEX_INLINEP int | swap (int newval) throw () |
QMUTEX_INLINEP int | cmpX (int compare, int newval) throw () |
Friends | |
class | QMutex |
class | QShrdMemMutex |
QMUTEX_INLINEP FX::FXAtomicInt::FXAtomicInt | ( | int | i = 0 |
) | throw () [inline] |
Constructs an atomic int with the specified initial value.
QMUTEX_INLINEP FX::FXAtomicInt::operator int | ( | ) | const throw () |
Returns the current value.
QMUTEX_INLINEP int FX::FXAtomicInt::operator= | ( | int | i | ) | throw () |
Atomically sets the value, bypassing caches and write buffers.
QMUTEX_INLINEP int FX::FXAtomicInt::operator++ | ( | int | ) | throw () |
Atomically post-increments the value.
QMUTEX_INLINEP int FX::FXAtomicInt::operator++ | ( | ) | throw () |
Atomically pre-increments the value.
QMUTEX_INLINEP int FX::FXAtomicInt::fastinc | ( | ) | throw () |
Atomically fast pre-increments the value, returning a negative number if result is negative, zero if result is zero and a positive number of result is positive
QMUTEX_INLINEP int FX::FXAtomicInt::operator+= | ( | int | i | ) | throw () |
Atomically adds an amount to the value.
QMUTEX_INLINEP int FX::FXAtomicInt::operator-- | ( | int | ) | throw () |
Atomically post-decrements the value.
QMUTEX_INLINEP int FX::FXAtomicInt::operator-- | ( | ) | throw () |
Atomically pre-decrements the value.
QMUTEX_INLINEP int FX::FXAtomicInt::fastdec | ( | ) | throw () |
Atomically fast pre-decrements the value, returning a negative number if result is negative, zero if result is zero and a positive number of result is positive
QMUTEX_INLINEP int FX::FXAtomicInt::operator-= | ( | int | i | ) | throw () |
Atomically subtracts an amount from the value.
QMUTEX_INLINEP int FX::FXAtomicInt::swap | ( | int | newval | ) | throw () |
Atomically swaps newval for the int, returning the previous value.
QMUTEX_INLINEP int FX::FXAtomicInt::cmpX | ( | int | compare, | |
int | newval | |||
) | throw () |
Atomically compares the int to compare which if the same, stores newval. Returns the previous value.