summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qyieldcpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread/qyieldcpu.h')
-rw-r--r--src/corelib/thread/qyieldcpu.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/corelib/thread/qyieldcpu.h b/src/corelib/thread/qyieldcpu.h
new file mode 100644
index 0000000000..d5da58deeb
--- /dev/null
+++ b/src/corelib/thread/qyieldcpu.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// Copyright (C) 2023 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QYIELDCPU_H
+#define QYIELDCPU_H
+
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qprocessordetection.h>
+#include <QtCore/qtconfigmacros.h>
+
+#ifdef Q_CC_MSVC_ONLY
+// MSVC defines _YIELD_PROCESSOR() in <xatomic.h>, but as that is a private
+// header, we include the public ones
+# ifdef __cplusplus
+# include <atomic>
+extern "C"
+# endif
+void _mm_pause(void); // the compiler recognizes as intrinsic
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_CC_GNU
+__attribute__((artificial))
+#endif
+Q_ALWAYS_INLINE void qYieldCpu(void) Q_DECL_NOEXCEPT;
+
+void qYieldCpu(void)
+#ifdef __cplusplus
+ noexcept
+#endif
+{
+#if __has_builtin(__yield)
+ __yield(); // Generic
+#elif defined(_YIELD_PROCESSOR) && defined(Q_CC_MSVC)
+ _YIELD_PROCESSOR(); // Generic; MSVC's <atomic>
+
+#elif __has_builtin(__builtin_ia32_pause)
+ __builtin_ia32_pause();
+#elif defined(Q_PROCESSOR_X86) && defined(Q_CC_GNU)
+ // GCC < 10 didn't have __has_builtin()
+ __builtin_ia32_pause();
+#elif defined(Q_PROCESSOR_X86) && defined(Q_CC_MSVC)
+ _mm_pause();
+#elif defined(Q_PROCESSOR_X86)
+ asm("pause"); // hopefully asm() works in this compiler
+
+#elif __has_builtin(__builtin_arm_yield)
+ __builtin_arm_yield();
+#elif defined(Q_PROCESSOR_ARM) && Q_PROCESSOR_ARM >= 7 && defined(Q_CC_GNU)
+ asm("yield"); // this works everywhere
+
+#elif defined(Q_PROCESSOR_RISCV)
+ asm(".word 0x0100000f"); // a.k.a. "pause"
+
+#elif defined(_YIELD_PROCESSOR) && defined(Q_CC_GHS)
+ _YIELD_PROCESSOR; // Green Hills (INTEGRITY), but only on ARM
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif // QYIELDCPU_H