diff src/atomic/win32/SDL_atomic.c @ 3306:a8ec88ff18c7

This version actaully should work on Windows.
author Bob Pendleton <bob@pendleton.com>
date Fri, 25 Sep 2009 19:17:16 +0000
parents 72b542f34739
children 0e000afe3dc0
line wrap: on
line diff
--- a/src/atomic/win32/SDL_atomic.c	Thu Sep 24 15:20:11 2009 +0000
+++ b/src/atomic/win32/SDL_atomic.c	Fri Sep 25 19:17:16 2009 +0000
@@ -26,6 +26,7 @@
 #include "SDL_atomic.h"
 
 #include "SDL_error.h"
+#include "Windows.h"
 
 /*
   This file provides 32, and 64 bit atomic operations. If the
@@ -36,12 +37,9 @@
 */
 
 /* 
-  DUMMY VERSION.
+  WIN32 VERSION.
 
-  This version of the code assumes there is no support for atomic
-  operations. Therefore, every function sets the SDL error
-  message. Oddly enough, if you only have one thread then this
-  version actuallys works.
+  This makes use of native Windows atomic operations.
 */
 
 /*
@@ -52,13 +50,24 @@
 void 
 SDL_AtomicLock(SDL_SpinLock *lock)
 {
-   SDL_SetError("SDL_atomic.c: is not implemented on this platform");
+  long volatile * l = (long volatile *)lock;
+  Uint32 old = 0;
+  Uint32 new = 1;
+
+  old = InterlockedExchange(l, new);
+  while(1 == old)
+    {
+      old = InterlockedExchange(l, new);
+    }
 }
 
 void 
 SDL_AtomicUnlock(SDL_SpinLock *lock)
 {
-   SDL_SetError("SDL_atomic.c: is not implemented on this platform");
+  long volatile * l = (long volatile *)lock;
+  Uint32 new = 0;
+
+  InterlockedExchange(l, new);
 }
 
 /*
@@ -67,16 +76,16 @@
   code.
 */
 
-#undef  nativeTestThenSet32
-#undef  nativeClear32
-#undef  nativeFetchThenIncrement32
-#undef  nativeFetchThenDecrement32
-#undef  nativeFetchThenAdd32
-#undef  nativeFetchThenSubtract32
-#undef  nativeIncrementThenFetch32
-#undef  nativeDecrementThenFetch32
-#undef  nativeAddThenFetch32
-#undef  nativeSubtractThenFetch32
+#define nativeTestThenSet32
+#define nativeClear32
+#define nativeFetchThenIncrement32
+#define nativeFetchThenDecrement32
+#define nativeFetchThenAdd32
+#define nativeFetchThenSubtract32
+#define nativeIncrementThenFetch32
+#define nativeDecrementThenFetch32
+#define nativeAddThenFetch32
+#define nativeSubtractThenFetch32
 
 #undef  nativeTestThenSet64
 #undef  nativeClear64
@@ -147,6 +156,10 @@
 SDL_AtomicTestThenSet32(volatile Uint32 * ptr)
 {
 #ifdef nativeTestThenSet32
+  long volatile * p = (long volatile *)ptr;
+  Uint32 new = 1;
+
+  return 0 == InterlockedExchange(p, new);
 #else
    SDL_bool result = SDL_FALSE;
 
@@ -166,6 +179,10 @@
 SDL_AtomicClear32(volatile Uint32 * ptr)
 {
 #ifdef nativeClear32
+  long volatile * p = (long volatile *)ptr;
+  Uint32 new = 0;
+
+  InterlockedExchange(p, new);
 #else
    privateWaitLock(ptr);
    *ptr = 0;
@@ -179,6 +196,9 @@
 SDL_AtomicFetchThenIncrement32(volatile Uint32 * ptr)
 {
 #ifdef nativeFetchThenIncrement32
+  long volatile * p = (long volatile *)ptr;
+
+  return InterlockedExchangeAdd(p, 1);
 #else
    Uint32 tmp = 0;
 
@@ -195,6 +215,9 @@
 SDL_AtomicFetchThenDecrement32(volatile Uint32 * ptr)
 {
 #ifdef nativeFetchThenDecrement32
+  long volatile * p = (long volatile *)ptr;
+
+  return InterlockedExchangeAdd(p, -1);
 #else
    Uint32 tmp = 0;
 
@@ -211,6 +234,9 @@
 SDL_AtomicFetchThenAdd32(volatile Uint32 * ptr, Uint32 value)
 {
 #ifdef nativeFetchThenAdd32
+  long volatile * p = (long volatile *)ptr;
+
+  return InterlockedExchangeAdd(p, value);
 #else
    Uint32 tmp = 0;
 
@@ -227,6 +253,9 @@
 SDL_AtomicFetchThenSubtract32(volatile Uint32 * ptr, Uint32 value)
 {
 #ifdef nativeFetchThenSubtract32
+  long volatile * p = (long volatile *)ptr;
+
+  return InterlockedExchangeAdd(p, (0 - value));
 #else
    Uint32 tmp = 0;
 
@@ -243,6 +272,9 @@
 SDL_AtomicIncrementThenFetch32(volatile Uint32 * ptr)
 {
 #ifdef nativeIncrementThenFetch32
+  long volatile * p = (LONG volatile *)ptr;
+
+  return InterlockedIncrement(p);
 #else
    Uint32 tmp = 0;
 
@@ -259,6 +291,9 @@
 SDL_AtomicDecrementThenFetch32(volatile Uint32 * ptr)
 {
 #ifdef nativeDecrementThenFetch32
+  long volatile * p = (LONG volatile *)ptr;
+
+  return InterlockedDecrement(p);
 #else
    Uint32 tmp = 0;
 
@@ -275,6 +310,9 @@
 SDL_AtomicAddThenFetch32(volatile Uint32 * ptr, Uint32 value)
 {
 #ifdef nativeAddThenFetch32
+  long volatile * p = (long volatile *)ptr;
+
+  return InterlockedExchangeAdd(p, value) + value;
 #else
    Uint32 tmp = 0;
 
@@ -291,6 +329,9 @@
 SDL_AtomicSubtractThenFetch32(volatile Uint32 * ptr, Uint32 value)
 {
 #ifdef nativeSubtractThenFetch32
+  long volatile * p = (long volatile *)ptr;
+
+  return InterlockedExchangeAdd(p, (0 - value)) - value;
 #else
    Uint32 tmp = 0;