summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfutureinterface.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-04-25 14:21:34 -0700
committerThiago Macieira <thiago.macieira@intel.com>2022-04-26 19:38:12 -0700
commitf02879a97a6e7587a7e116f85d6a153f616a5d3f (patch)
treee0e6caf0f3adbe8b4c3121e7b8d880b4a75d5e6a /src/corelib/thread/qfutureinterface.cpp
parentf3640d908633b0e512077f24c41eca851879f0ed (diff)
QFutureInterface: insert x86 PAUSE in tight CMPXCHG loop
From the Intel Software Optimization Manual[1], Chapter 11 ("Multi-core and Hyper-Threading Technology"), offers: User/Source Coding Rule 14. (M impact, H generality) Insert the PAUSE instruction in fast spin loops and keep the number of loop repetitions to a minimum to improve overall system performance. See section 11.4.2 for an explanation of why this is a good idea. [1] https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html#inpage-nav-5 Pick-to: 6.3 Change-Id: I7fb65b80b7844c8d8f26fffd16e94088dad1ceee Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Diffstat (limited to 'src/corelib/thread/qfutureinterface.cpp')
-rw-r--r--src/corelib/thread/qfutureinterface.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index 71d6670538..a54caa878b 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -45,6 +45,10 @@
#include <QtCore/qthread.h>
#include <private/qthreadpool_p.h>
+#ifdef Q_PROCESSOR_X86
+# include <immintrin.h> // for _mm_pause()
+#endif
+
#ifdef interface
# undef interface
#endif
@@ -106,9 +110,14 @@ static inline int switch_from_to(QAtomicInt &a, int from, int to)
{
int newValue;
int expected = a.loadRelaxed();
- do {
+ for (;;) {
newValue = (expected & ~from) | to;
- } while (!a.testAndSetRelaxed(expected, newValue, expected));
+ if (a.testAndSetRelaxed(expected, newValue, expected))
+ break;
+#ifdef Q_PROCESSOR_X86
+ _mm_pause();
+#endif
+ }
return newValue;
}