summaryrefslogtreecommitdiff
path: root/Source/3rdParty/SDL2/src/atomic/SDL_spinlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/3rdParty/SDL2/src/atomic/SDL_spinlock.c')
-rw-r--r--Source/3rdParty/SDL2/src/atomic/SDL_spinlock.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/Source/3rdParty/SDL2/src/atomic/SDL_spinlock.c b/Source/3rdParty/SDL2/src/atomic/SDL_spinlock.c
index 1ebc718..6a7b14a 100644
--- a/Source/3rdParty/SDL2/src/atomic/SDL_spinlock.c
+++ b/Source/3rdParty/SDL2/src/atomic/SDL_spinlock.c
@@ -32,11 +32,15 @@
#include <atomic.h>
#endif
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+#include <xmmintrin.h>
+#endif
+
#if defined(__WATCOMC__) && defined(__386__)
SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
#pragma aux _SDL_xchg_watcom = \
- "xchg [ecx], eax" \
+ "lock xchg [ecx], eax" \
parm [ecx] [eax] \
value [eax] \
modify exact [eax];
@@ -116,12 +120,32 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
#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(_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(__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
SDL_AtomicLock(SDL_SpinLock *lock)
{
+ int iterations = 0;
/* FIXME: Should we have an eventual timeout? */
while (!SDL_AtomicTryLock(lock)) {
- SDL_Delay(0);
+ if (iterations < 32) {
+ iterations++;
+ PAUSE_INSTRUCTION();
+ } else {
+ /* !!! FIXME: this doesn't definitely give up the current timeslice, it does different things on various platforms. */
+ SDL_Delay(0);
+ }
}
}