2620 solaris port missing atomics if not using gcc
authorShawn Walker <binarycrusader@gmail.com>
Sat, 05 Jul 2014 16:11:23 -0700
changeset 8979 1e283b7a1580
parent 8978 7753e4fd3d1d
child 8980 66824b0e330a
2620 solaris port missing atomics if not using gcc
include/SDL_atomic.h
include/SDL_platform.h
src/atomic/SDL_atomic.c
src/atomic/SDL_spinlock.c
test/Makefile.in
--- a/include/SDL_atomic.h	Mon Jul 07 10:33:32 2014 -0700
+++ b/include/SDL_atomic.h	Sat Jul 05 16:11:23 2014 -0700
@@ -122,7 +122,8 @@
 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 @@
 #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
--- a/include/SDL_platform.h	Mon Jul 07 10:33:32 2014 -0700
+++ b/include/SDL_platform.h	Sat Jul 05 16:11:23 2014 -0700
@@ -109,7 +109,7 @@
 #undef __RISCOS__
 #define __RISCOS__  1
 #endif
-#if defined(__SVR4)
+#if defined(__sun) && defined(__SVR4)
 #undef __SOLARIS__
 #define __SOLARIS__ 1
 #endif
--- a/src/atomic/SDL_atomic.c	Mon Jul 07 10:33:32 2014 -0700
+++ b/src/atomic/SDL_atomic.c	Sat Jul 05 16:11:23 2014 -0700
@@ -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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 {
--- a/src/atomic/SDL_spinlock.c	Mon Jul 07 10:33:32 2014 -0700
+++ b/src/atomic/SDL_spinlock.c	Sat Jul 05 16:11:23 2014 -0700
@@ -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 @@
     /* 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 @@
 #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
--- a/test/Makefile.in	Mon Jul 07 10:33:32 2014 -0700
+++ b/test/Makefile.in	Sat Jul 05 16:11:23 2014 -0700
@@ -10,6 +10,7 @@
 TARGETS = \
 	checkkeys$(EXE) \
 	loopwave$(EXE) \
+	testatomic$(EXE) \
 	testaudioinfo$(EXE) \
 	testautomation$(EXE) \
 	testdraw2$(EXE) \