There is a RequestQueue request queue class:
QQueue<Request> _requests; QAtomicInt _locker; void RequestQueue::enqueue(const Request &request) { while(_locker.testAndSetOrdered(0,1) == false) QThread::yieldCurrentThread(); _requests.enqueue(request); _locker = 0; } Request RequestQueue::dequeue() { forever { if(_locker.testAndSetOrdered(0,1) == true) { if(_requests.isEmpty() == true) { _locker = 0; break; } const Request request = _requests.dequeue(); _locker = 0; return request; } QThread::yieldCurrentThread(); } return Request(); } I decided to try the implementation without mutexes, since there are a lot of threads competing with each other, both on writing to the queue and reading from it, and I wanted to get the maximum possible acceleration.
The code works correctly, but it is confusing to not understand which method should be used for test-and-set . In the example above, this is QAtomicInteger::testAndSetOrdered() , but why not use, say, QAtomicInteger::testAndSetRelaxed() or another one of the other two remaining options instead.
Help is not very verbose about this (however, I admit that I just translate incorrectly):
QAtomicInteger provides for at-test-and-set, fetch-and-store, and fetch-and-add functions. Each implementation defines a sequence of ordering instructions. Since it’s out of the order of execution and memory ordering, it’s necessary to ensure that your application rules for all processors.
Which of the variants of memory ordering may be preferable for choosing specifically in the situation with an example from my question?
testAndSetOrdereduntil you clearly understand what works and how. Or even forget about such low-level optimizations. I wrote about this (not Qt, but the essence of one) article: one , two and three . Reading all three will help clarify the issue a bit, I hope - ixSci