2620 solaris port missing atomics if not using gcc

This commit is contained in:
Shawn Walker 2014-07-05 16:11:23 -07:00
parent d44f392265
commit c5812c5511
5 changed files with 53 additions and 3 deletions

View File

@ -122,7 +122,8 @@ extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
void _ReadWriteBarrier(void); void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier) #pragma intrinsic(_ReadWriteBarrier)
#define SDL_CompilerBarrier() _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") #define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory")
#else #else
#define SDL_CompilerBarrier() \ #define SDL_CompilerBarrier() \
@ -169,10 +170,17 @@ extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquire();
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory") #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory")
#endif /* __GNUC__ && __arm__ */ #endif /* __GNUC__ && __arm__ */
#else #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. */ /* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier() #define SDL_MemoryBarrierRelease() SDL_CompilerBarrier()
#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier() #define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier()
#endif #endif
#endif
/** /**
* \brief A type representing an atomic integer value. It is a struct * \brief A type representing an atomic integer value. It is a struct

View File

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

View File

@ -31,6 +31,10 @@
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
#endif #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 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 of them. That means we need a nice implementation of spin locks
@ -54,7 +58,7 @@
Contributed by Bob Pendleton, bob@pendleton.com 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 #define EMULATE_CAS 1
#endif #endif
@ -88,6 +92,10 @@ SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value); return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
#elif defined(HAVE_GCC_ATOMICS) #elif defined(HAVE_GCC_ATOMICS)
return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval); 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 #elif EMULATE_CAS
SDL_bool retval = SDL_FALSE; 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); return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a);
#elif defined(HAVE_GCC_ATOMICS) #elif defined(HAVE_GCC_ATOMICS)
return __sync_bool_compare_and_swap(a, oldval, newval); 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 #elif EMULATE_CAS
SDL_bool retval = SDL_FALSE; SDL_bool retval = SDL_FALSE;
@ -140,6 +150,10 @@ SDL_AtomicSet(SDL_atomic_t *a, int v)
return _InterlockedExchange((long*)&a->value, v); return _InterlockedExchange((long*)&a->value, v);
#elif defined(HAVE_GCC_ATOMICS) #elif defined(HAVE_GCC_ATOMICS)
return __sync_lock_test_and_set(&a->value, v); 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 #else
int value; int value;
do { do {
@ -158,6 +172,8 @@ SDL_AtomicSetPtr(void **a, void *v)
return _InterlockedExchangePointer(a, v); return _InterlockedExchangePointer(a, v);
#elif defined(HAVE_GCC_ATOMICS) #elif defined(HAVE_GCC_ATOMICS)
return __sync_lock_test_and_set(a, v); return __sync_lock_test_and_set(a, v);
#elif defined(__SOLARIS__)
return atomic_swap_ptr(a, v);
#else #else
void *value; void *value;
do { do {
@ -174,6 +190,15 @@ SDL_AtomicAdd(SDL_atomic_t *a, int v)
return _InterlockedExchangeAdd((long*)&a->value, v); return _InterlockedExchangeAdd((long*)&a->value, v);
#elif defined(HAVE_GCC_ATOMICS) #elif defined(HAVE_GCC_ATOMICS)
return __sync_fetch_and_add(&a->value, v); 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 #else
int value; int value;
do { do {

View File

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

View File

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