Bladeren bron

2620 solaris port missing atomics if not using gcc

Shawn Walker 10 jaren geleden
bovenliggende
commit
c5812c5511
5 gewijzigde bestanden met toevoegingen van 53 en 3 verwijderingen
  1. 9 1
      include/SDL_atomic.h
  2. 1 1
      include/SDL_platform.h
  3. 26 1
      src/atomic/SDL_atomic.c
  4. 16 0
      src/atomic/SDL_spinlock.c
  5. 1 0
      test/Makefile.in

+ 9 - 1
include/SDL_atomic.h

@@ -122,7 +122,8 @@ extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
 void _ReadWriteBarrier(void);
 #pragma intrinsic(_ReadWriteBarrier)
 #define SDL_CompilerBarrier()   _ReadWriteBarrier()
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
+/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
 #define SDL_CompilerBarrier()   __asm__ __volatile__ ("" : : : "memory")
 #else
 #define SDL_CompilerBarrier()   \
@@ -169,10 +170,17 @@ extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquire();
 #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("" : : : "memory")
 #endif /* __GNUC__ && __arm__ */
 #else
+#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
+/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */
+#include <mbarrier.h>
+#define SDL_MemoryBarrierRelease()  __machine_rel_barrier()
+#define SDL_MemoryBarrierAcquire()  __machine_acq_barrier()
+#else
 /* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
 #define SDL_MemoryBarrierRelease()  SDL_CompilerBarrier()
 #define SDL_MemoryBarrierAcquire()  SDL_CompilerBarrier()
 #endif
+#endif
 
 /**
  * \brief A type representing an atomic integer value.  It is a struct

+ 1 - 1
include/SDL_platform.h

@@ -109,7 +109,7 @@
 #undef __RISCOS__
 #define __RISCOS__  1
 #endif
-#if defined(__SVR4)
+#if defined(__sun) && defined(__SVR4)
 #undef __SOLARIS__
 #define __SOLARIS__ 1
 #endif

+ 26 - 1
src/atomic/SDL_atomic.c

@@ -31,6 +31,10 @@
 #include <libkern/OSAtomic.h>
 #endif
 
+#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
+#include <atomic.h>
+#endif
+
 /*
   If any of the operations are not provided then we must emulate some
   of them. That means we need a nice implementation of spin locks
@@ -54,7 +58,7 @@
   Contributed by Bob Pendleton, bob@pendleton.com
 */
 
-#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__)
+#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__)
 #define EMULATE_CAS 1
 #endif
 
@@ -88,6 +92,10 @@ SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
     return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
 #elif defined(HAVE_GCC_ATOMICS)
     return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval);
+#elif defined(__SOLARIS__) && defined(_LP64)
+    return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)&a->value, (uint64_t)oldval, (uint64_t)newval) == oldval);
+#elif defined(__SOLARIS__) && !defined(_LP64)
+    return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)&a->value, (uint32_t)oldval, (uint32_t)newval) == oldval);
 #elif EMULATE_CAS
     SDL_bool retval = SDL_FALSE;
 
@@ -117,6 +125,8 @@ SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
     return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a);
 #elif defined(HAVE_GCC_ATOMICS)
     return __sync_bool_compare_and_swap(a, oldval, newval);
+#elif defined(__SOLARIS__)
+    return (SDL_bool) (atomic_cas_ptr(a, oldval, newval) == oldval);
 #elif EMULATE_CAS
     SDL_bool retval = SDL_FALSE;
 
@@ -140,6 +150,10 @@ SDL_AtomicSet(SDL_atomic_t *a, int v)
     return _InterlockedExchange((long*)&a->value, v);
 #elif defined(HAVE_GCC_ATOMICS)
     return __sync_lock_test_and_set(&a->value, v);
+#elif defined(__SOLARIS__) && defined(_LP64)
+    return (int) atomic_swap_64((volatile uint64_t*)&a->value, (uint64_t)v);
+#elif defined(__SOLARIS__) && !defined(_LP64)
+    return (int) atomic_swap_32((volatile uint32_t*)&a->value, (uint32_t)v);
 #else
     int value;
     do {
@@ -158,6 +172,8 @@ SDL_AtomicSetPtr(void **a, void *v)
     return _InterlockedExchangePointer(a, v);
 #elif defined(HAVE_GCC_ATOMICS)
     return __sync_lock_test_and_set(a, v);
+#elif defined(__SOLARIS__)
+    return atomic_swap_ptr(a, v);
 #else
     void *value;
     do {
@@ -174,6 +190,15 @@ SDL_AtomicAdd(SDL_atomic_t *a, int v)
     return _InterlockedExchangeAdd((long*)&a->value, v);
 #elif defined(HAVE_GCC_ATOMICS)
     return __sync_fetch_and_add(&a->value, v);
+#elif defined(__SOLARIS__)
+    int pv = a->value;
+    membar_consumer();
+#if defined(_LP64)
+    atomic_add_64((volatile uint64_t*)&a->value, v);
+#elif !defined(_LP64)
+    atomic_add_32((volatile uint32_t*)&a->value, v);
+#endif
+    return pv;
 #else
     int value;
     do {

+ 16 - 0
src/atomic/SDL_spinlock.c

@@ -28,6 +28,9 @@
 #include "SDL_mutex.h"
 #include "SDL_timer.h"
 
+#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
+#include <atomic.h>
+#endif
 
 /* This function is where all the magic happens... */
 SDL_bool
@@ -90,6 +93,14 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
     /* pthread instructions */
     return (pthread_spin_trylock(lock) == 0);
 
+#elif defined(__SOLARIS__) && defined(_LP64)
+    /* Used for Solaris with non-gcc compilers. */
+    return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)lock, 0, 1) == 0);
+
+#elif defined(__SOLARIS__) && !defined(_LP64)
+    /* Used for Solaris with non-gcc compilers. */
+    return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0);
+
 #else
 #error Please implement for your platform.
     return SDL_FALSE;
@@ -118,6 +129,11 @@ SDL_AtomicUnlock(SDL_SpinLock *lock)
 #elif HAVE_PTHREAD_SPINLOCK
     pthread_spin_unlock(lock);
 
+#elif defined(__SOLARIS__)
+    /* Used for Solaris when not using gcc. */
+    *lock = 0;
+    membar_producer();
+
 #else
     *lock = 0;
 #endif

+ 1 - 0
test/Makefile.in

@@ -10,6 +10,7 @@ LIBS	= @LIBS@
 TARGETS = \
 	checkkeys$(EXE) \
 	loopwave$(EXE) \
+	testatomic$(EXE) \
 	testaudioinfo$(EXE) \
 	testautomation$(EXE) \
 	testdraw2$(EXE) \