From c847f0091d484de7b3fb1049838eee3f2ac3dfc5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 30 Apr 2022 10:21:26 +0200 Subject: 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 Reviewed-by: Qt CI Bot --- src/corelib/thread/qfutureinterface.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'src/corelib/thread/qfutureinterface.cpp') diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index a54caa878b..efbcf9ce58 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -43,12 +43,9 @@ #include #include +#include // for qYieldCpu() #include -#ifdef Q_PROCESSOR_X86 -# include // 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() -- cgit v1.2.3