Add ARM YIELD support to qYieldCpu()
YIELD is ARM's equivalent of x86's PAUSE, available since ARMv6k, which should be old enough that we can use it unconditionally. The ARM manual[1] defines the __yield() intrinsic for this, however: - Clang has __builtin_arm_yield, the naming is compatible with what GCC would use, so we use that if available, to avoid having to include even more headers. - GCC (incl. 12) doesn't have __yield() in arm_acle.h or anywhere else, and it doesn't seem to have the builtin (yet, one can always hope), so we use asm() there. - Windows doesn't have an arm_acle.h header, but the docs[2] say it should have __yield(). Unfortunately, the docs don't say where the intrinsic is hiding, but we already include <intrin.h>, and godbolt[3] confirms that's sufficient to use __yield(). We could use YieldProcessor(), but we'd need to include qt_windows.h, I guess, which I'd rather not. - Integrity doesn't have the arm_acle.h header, we use asm(), here, too. [1] https://developer.arm.com/documentation/dui0472/k/Compiler-specific-Features/--yield-intrinsic [2] https://docs.microsoft.com/en-us/cpp/intrinsics/arm-intrinsics?view=msvc-140 [3] https://godbolt.org/z/Evfe79xhE Pick-to: 6.3 Fixes: QTBUG-103011 Change-Id: Ibf496dfe9949f9a3d24c0dcf75a703c5fdbbb4b8 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
71322ef361
commit
877c158c59
@ -395,7 +395,7 @@ static inline uint64_t qCpuFeatures()
|
||||
|| ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature))
|
||||
|
||||
/*
|
||||
Small wrapper around x86's PAUSE instruction.
|
||||
Small wrapper around x86's PAUSE and ARM's YIELD instructions.
|
||||
|
||||
This is completely different from QThread::yieldCurrentThread(), which is
|
||||
an OS-level operation that takes the whole thread off the CPU.
|
||||
@ -420,6 +420,21 @@ static inline void qYieldCpu()
|
||||
{
|
||||
#if defined(Q_PROCESSOR_X86)
|
||||
_mm_pause();
|
||||
#elif defined(Q_PROCESSOR_ARM)
|
||||
# if __has_builtin(__builtin_arm_yield) /* e.g. Clang */
|
||||
__builtin_arm_yield();
|
||||
# elif defined(Q_OS_INTEGRITY) || \
|
||||
(defined(Q_CC_GNU) && !defined(Q_CC_CLANG))
|
||||
/*
|
||||
- Integrity is missing the arm_acle.h header
|
||||
- GCC doesn't have __yield() in arm_acle.h
|
||||
https://stackoverflow.com/a/70076751/134841
|
||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105416
|
||||
*/
|
||||
asm volatile("yield"); /* this works everywhere */
|
||||
# else
|
||||
__yield(); /* this is what should work everywhere */
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user