QFutureInterface: use (new) qYieldCpu() instead of _mm_pause()
This loop here was a lonesome instance of a CAS loop in which adding _mm_pause() was simple, because the code didn't use the usual pattern do { construct new value } while (!testAndSet) we use everywhere else in Qt. In search of an elegant pattern that would allow to apply qYieldCpu()/_mm_pause() to those idiomatic CAS loops, too, I've reached for a lambda to construct the new value. This should apply to all (tight) CAS loops, and may form the basis of an API extension whereby we take that lambda as a function argument to encapsulate the CAS loop in an algorithm (a function). Pick-to: 6.3 Change-Id: Id4a8f174dd812aa26f0b163e943bd4558e5e6a7b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
1808df9ce5
commit
c847f0091d
@ -43,12 +43,9 @@
|
||||
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qthread.h>
|
||||
#include <QtCore/private/qsimd_p.h> // for qYieldCpu()
|
||||
#include <private/qthreadpool_p.h>
|
||||
|
||||
#ifdef Q_PROCESSOR_X86
|
||||
# include <immintrin.h> // for _mm_pause()
|
||||
#endif
|
||||
|
||||
#ifdef interface
|
||||
# undef interface
|
||||
#endif
|
||||
@ -108,17 +105,11 @@ static inline int switch_off(QAtomicInt &a, int which)
|
||||
|
||||
static inline int switch_from_to(QAtomicInt &a, int from, int to)
|
||||
{
|
||||
int newValue;
|
||||
int expected = a.loadRelaxed();
|
||||
for (;;) {
|
||||
newValue = (expected & ~from) | to;
|
||||
if (a.testAndSetRelaxed(expected, newValue, expected))
|
||||
break;
|
||||
#ifdef Q_PROCESSOR_X86
|
||||
_mm_pause();
|
||||
#endif
|
||||
}
|
||||
return newValue;
|
||||
const auto adjusted = [&](int old) { return (old & ~from) | to; };
|
||||
int value = a.loadRelaxed();
|
||||
while (!a.testAndSetRelaxed(value, adjusted(value), value))
|
||||
qYieldCpu();
|
||||
return value;
|
||||
}
|
||||
|
||||
void QFutureInterfaceBase::cancel()
|
||||
|
Loading…
x
Reference in New Issue
Block a user