Kill util/spinlock.h, it is actually worse than QMutex in every case
QMutex has changed a lot since this code was introduced and now has the
same kind of logic as SpinLock internally, but implements it a lot more
efficiently. Instead of requiring a QMutex::lock() call and a call to
QWaitCondition::wait() (which is two more compare-and-swap instructions)
it directly uses the futex() syscall.
There are also a few problems with the spinlock code:
- It spins using testAndSetOrdered() instead of testAndSetRelaxed().
- There is also no need to unlock using sequentially consistent order,
storeRelease() is enough.
- Even worse is the fact that it uses compare-and-swap
(QAtomicInt::testAndSet*()) for the spinlock, instead of test-and-set
(QAtomicInt::fetchAndStore*()) which would be a lot faster.
- For handling locking with timeout Spinlock uses gettimeofday() which
is not available on e.g. Windows.
- Finally, the class is poorly named, it isn't a spinlock since it
sleeps in every loop iteration instead of continuously attempting to
acquire the lock.
A class that actually tries spinning on the lock for a few iterations
before taking the slow path that sleeps MIGHT improve the throughput.
However, finding the right count is hard and will decrease performance
if not chosen correctly.
The easiest way to gain a bit of performance in the locking code would
be to use QBasicMutex for all non-recursive QMutexes, since that would
allow inlining of the fast path lock() code. But since the class is not
documented as public we should probably not do that.
REVIEW: 121570