Proposing exposing as public api the various arch dependent

pause instructions so could be used in app infinite loops.
A handful of games do already so we unify it in one place.
This commit is contained in:
David Carlier 2022-08-01 07:59:04 +01:00 committed by Sam Lantinga
parent 43b90484c9
commit 16e699a761
2 changed files with 21 additions and 20 deletions

View File

@ -237,6 +237,26 @@ typedef void (*SDL_KernelMemoryBarrierFunc)();
#endif #endif
#endif #endif
/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
#define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
#elif (defined(__arm__) && __ARM_ARCH__ >= 7) || defined(__aarch64__)
#define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory")
#elif (defined(__powerpc__) || defined(__powerpc64__))
#define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27");
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
#define SDL_CPUPauseInstruction() __yield()
#elif defined(__WATCOMC__) && defined(__386__)
/* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes. */
extern __inline void SDL_CPUPauseInstruction(void);
#pragma aux SDL_CPUPauseInstruction = "db 0f3h,90h"
#else
#define SDL_CPUPauseInstruction()
#endif
/** /**
* \brief A type representing an atomic integer value. It is a struct * \brief A type representing an atomic integer value. It is a struct
* so people don't accidentally use numeric operations on it. * so people don't accidentally use numeric operations on it.

View File

@ -158,25 +158,6 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
#endif #endif
} }
/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
#define PAUSE_INSTRUCTION() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
#elif (defined(__arm__) && __ARM_ARCH__ >= 7) || defined(__aarch64__)
#define PAUSE_INSTRUCTION() __asm__ __volatile__("yield" ::: "memory")
#elif (defined(__powerpc__) || defined(__powerpc64__))
#define PAUSE_INSTRUCTION() __asm__ __volatile__("or 27,27,27");
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#define PAUSE_INSTRUCTION() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
#define PAUSE_INSTRUCTION() __yield()
#elif defined(__WATCOMC__) && defined(__386__)
/* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes. */
extern __inline void PAUSE_INSTRUCTION(void);
#pragma aux PAUSE_INSTRUCTION = "db 0f3h,90h"
#else
#define PAUSE_INSTRUCTION()
#endif
void void
SDL_AtomicLock(SDL_SpinLock *lock) SDL_AtomicLock(SDL_SpinLock *lock)
{ {
@ -185,7 +166,7 @@ SDL_AtomicLock(SDL_SpinLock *lock)
while (!SDL_AtomicTryLock(lock)) { while (!SDL_AtomicTryLock(lock)) {
if (iterations < 32) { if (iterations < 32) {
iterations++; iterations++;
PAUSE_INSTRUCTION(); SDL_CPUPauseInstruction();
} else { } else {
/* !!! FIXME: this doesn't definitely give up the current timeslice, it does different things on various platforms. */ /* !!! FIXME: this doesn't definitely give up the current timeslice, it does different things on various platforms. */
SDL_Delay(0); SDL_Delay(0);