2620 solaris port missing atomics if not using gcc
authorShawn Walker <binarycrusader@gmail.com>
Sat, 05 Jul 2014 16:11:23 -0700
changeset 89791e283b7a1580
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
     1.1 --- a/include/SDL_atomic.h	Mon Jul 07 10:33:32 2014 -0700
     1.2 +++ b/include/SDL_atomic.h	Sat Jul 05 16:11:23 2014 -0700
     1.3 @@ -122,7 +122,8 @@
     1.4  void _ReadWriteBarrier(void);
     1.5  #pragma intrinsic(_ReadWriteBarrier)
     1.6  #define SDL_CompilerBarrier()   _ReadWriteBarrier()
     1.7 -#elif defined(__GNUC__)
     1.8 +#elif defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
     1.9 +/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
    1.10  #define SDL_CompilerBarrier()   __asm__ __volatile__ ("" : : : "memory")
    1.11  #else
    1.12  #define SDL_CompilerBarrier()   \
    1.13 @@ -169,10 +170,17 @@
    1.14  #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("" : : : "memory")
    1.15  #endif /* __GNUC__ && __arm__ */
    1.16  #else
    1.17 +#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
    1.18 +/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */
    1.19 +#include <mbarrier.h>
    1.20 +#define SDL_MemoryBarrierRelease()  __machine_rel_barrier()
    1.21 +#define SDL_MemoryBarrierAcquire()  __machine_acq_barrier()
    1.22 +#else
    1.23  /* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
    1.24  #define SDL_MemoryBarrierRelease()  SDL_CompilerBarrier()
    1.25  #define SDL_MemoryBarrierAcquire()  SDL_CompilerBarrier()
    1.26  #endif
    1.27 +#endif
    1.28  
    1.29  /**
    1.30   * \brief A type representing an atomic integer value.  It is a struct
     2.1 --- a/include/SDL_platform.h	Mon Jul 07 10:33:32 2014 -0700
     2.2 +++ b/include/SDL_platform.h	Sat Jul 05 16:11:23 2014 -0700
     2.3 @@ -109,7 +109,7 @@
     2.4  #undef __RISCOS__
     2.5  #define __RISCOS__  1
     2.6  #endif
     2.7 -#if defined(__SVR4)
     2.8 +#if defined(__sun) && defined(__SVR4)
     2.9  #undef __SOLARIS__
    2.10  #define __SOLARIS__ 1
    2.11  #endif
     3.1 --- a/src/atomic/SDL_atomic.c	Mon Jul 07 10:33:32 2014 -0700
     3.2 +++ b/src/atomic/SDL_atomic.c	Sat Jul 05 16:11:23 2014 -0700
     3.3 @@ -31,6 +31,10 @@
     3.4  #include <libkern/OSAtomic.h>
     3.5  #endif
     3.6  
     3.7 +#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
     3.8 +#include <atomic.h>
     3.9 +#endif
    3.10 +
    3.11  /*
    3.12    If any of the operations are not provided then we must emulate some
    3.13    of them. That means we need a nice implementation of spin locks
    3.14 @@ -54,7 +58,7 @@
    3.15    Contributed by Bob Pendleton, bob@pendleton.com
    3.16  */
    3.17  
    3.18 -#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__)
    3.19 +#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__)
    3.20  #define EMULATE_CAS 1
    3.21  #endif
    3.22  
    3.23 @@ -88,6 +92,10 @@
    3.24      return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
    3.25  #elif defined(HAVE_GCC_ATOMICS)
    3.26      return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval);
    3.27 +#elif defined(__SOLARIS__) && defined(_LP64)
    3.28 +    return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)&a->value, (uint64_t)oldval, (uint64_t)newval) == oldval);
    3.29 +#elif defined(__SOLARIS__) && !defined(_LP64)
    3.30 +    return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)&a->value, (uint32_t)oldval, (uint32_t)newval) == oldval);
    3.31  #elif EMULATE_CAS
    3.32      SDL_bool retval = SDL_FALSE;
    3.33  
    3.34 @@ -117,6 +125,8 @@
    3.35      return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a);
    3.36  #elif defined(HAVE_GCC_ATOMICS)
    3.37      return __sync_bool_compare_and_swap(a, oldval, newval);
    3.38 +#elif defined(__SOLARIS__)
    3.39 +    return (SDL_bool) (atomic_cas_ptr(a, oldval, newval) == oldval);
    3.40  #elif EMULATE_CAS
    3.41      SDL_bool retval = SDL_FALSE;
    3.42  
    3.43 @@ -140,6 +150,10 @@
    3.44      return _InterlockedExchange((long*)&a->value, v);
    3.45  #elif defined(HAVE_GCC_ATOMICS)
    3.46      return __sync_lock_test_and_set(&a->value, v);
    3.47 +#elif defined(__SOLARIS__) && defined(_LP64)
    3.48 +    return (int) atomic_swap_64((volatile uint64_t*)&a->value, (uint64_t)v);
    3.49 +#elif defined(__SOLARIS__) && !defined(_LP64)
    3.50 +    return (int) atomic_swap_32((volatile uint32_t*)&a->value, (uint32_t)v);
    3.51  #else
    3.52      int value;
    3.53      do {
    3.54 @@ -158,6 +172,8 @@
    3.55      return _InterlockedExchangePointer(a, v);
    3.56  #elif defined(HAVE_GCC_ATOMICS)
    3.57      return __sync_lock_test_and_set(a, v);
    3.58 +#elif defined(__SOLARIS__)
    3.59 +    return atomic_swap_ptr(a, v);
    3.60  #else
    3.61      void *value;
    3.62      do {
    3.63 @@ -174,6 +190,15 @@
    3.64      return _InterlockedExchangeAdd((long*)&a->value, v);
    3.65  #elif defined(HAVE_GCC_ATOMICS)
    3.66      return __sync_fetch_and_add(&a->value, v);
    3.67 +#elif defined(__SOLARIS__)
    3.68 +    int pv = a->value;
    3.69 +    membar_consumer();
    3.70 +#if defined(_LP64)
    3.71 +    atomic_add_64((volatile uint64_t*)&a->value, v);
    3.72 +#elif !defined(_LP64)
    3.73 +    atomic_add_32((volatile uint32_t*)&a->value, v);
    3.74 +#endif
    3.75 +    return pv;
    3.76  #else
    3.77      int value;
    3.78      do {
     4.1 --- a/src/atomic/SDL_spinlock.c	Mon Jul 07 10:33:32 2014 -0700
     4.2 +++ b/src/atomic/SDL_spinlock.c	Sat Jul 05 16:11:23 2014 -0700
     4.3 @@ -28,6 +28,9 @@
     4.4  #include "SDL_mutex.h"
     4.5  #include "SDL_timer.h"
     4.6  
     4.7 +#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
     4.8 +#include <atomic.h>
     4.9 +#endif
    4.10  
    4.11  /* This function is where all the magic happens... */
    4.12  SDL_bool
    4.13 @@ -90,6 +93,14 @@
    4.14      /* pthread instructions */
    4.15      return (pthread_spin_trylock(lock) == 0);
    4.16  
    4.17 +#elif defined(__SOLARIS__) && defined(_LP64)
    4.18 +    /* Used for Solaris with non-gcc compilers. */
    4.19 +    return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)lock, 0, 1) == 0);
    4.20 +
    4.21 +#elif defined(__SOLARIS__) && !defined(_LP64)
    4.22 +    /* Used for Solaris with non-gcc compilers. */
    4.23 +    return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0);
    4.24 +
    4.25  #else
    4.26  #error Please implement for your platform.
    4.27      return SDL_FALSE;
    4.28 @@ -118,6 +129,11 @@
    4.29  #elif HAVE_PTHREAD_SPINLOCK
    4.30      pthread_spin_unlock(lock);
    4.31  
    4.32 +#elif defined(__SOLARIS__)
    4.33 +    /* Used for Solaris when not using gcc. */
    4.34 +    *lock = 0;
    4.35 +    membar_producer();
    4.36 +
    4.37  #else
    4.38      *lock = 0;
    4.39  #endif
     5.1 --- a/test/Makefile.in	Mon Jul 07 10:33:32 2014 -0700
     5.2 +++ b/test/Makefile.in	Sat Jul 05 16:11:23 2014 -0700
     5.3 @@ -10,6 +10,7 @@
     5.4  TARGETS = \
     5.5  	checkkeys$(EXE) \
     5.6  	loopwave$(EXE) \
     5.7 +	testatomic$(EXE) \
     5.8  	testaudioinfo$(EXE) \
     5.9  	testautomation$(EXE) \
    5.10  	testdraw2$(EXE) \