diff options
author | Chris Robinson <[email protected]> | 2011-09-23 12:42:13 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2011-09-23 12:42:13 -0700 |
commit | ff8ee688526d4ad994eb72589fe0a294d14bd754 (patch) | |
tree | 7e737bbd5db252443259622549fe878f1d890aa2 | |
parent | 470b506952c83580cfae5c3dc94a3b359c900dea (diff) |
Add atomic functions for GCC inline asm
-rw-r--r-- | OpenAL32/Include/alMain.h | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 7bcbef8f..f23a6507 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -239,6 +239,76 @@ static __inline ALboolean CompExchangePtr(void *volatile*ptr, void *oldval, void return __sync_bool_compare_and_swap(ptr, oldval, newval); } +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +static __inline int xaddl(volatile int *dest, int incr) +{ + int ret; + __asm__ __volatile__("lock; xaddl %0,(%1)" + : "=r" (ret) + : "r" (dest), "0" (incr) + : "memory"); + return ret; +} + +typedef int RefCount; +static __inline RefCount IncrementRef(volatile RefCount *ptr) +{ return xaddl(ptr, 1)+1; } +static __inline RefCount DecrementRef(volatile RefCount *ptr) +{ return xaddl(ptr, -1)-1; } + +static __inline int ExchangeInt(volatile int *dest, int newval) +{ + int ret; + __asm__ __volatile__("lock; xchgl %0,(%1)" + : "=r" (ret) + : "r" (dest), "0" (newval) + : "memory"); + return ret; +} + +static __inline ALboolean CompExchangeInt(volatile int *dest, int oldval, int newval) +{ + int ret; + __asm__ __volatile__("lock; cmpxchgl %2,(%1)" + : "=a" (ret) + : "r" (dest), "r" (newval), "0" (oldval) + : "memory"); + return ret == oldval; +} + +static __inline void *ExchangePtr(void *volatile*dest, void *newval) +{ + void *ret; + __asm__ __volatile__( +#ifdef __i386__ + "lock; xchgl %0,(%1)" +#else + "lock; xchgq %0,(%1)" +#endif + : "=r" (ret) + : "r" (dest), "0" (newval) + : "memory" + ); + return ret; +} + +static __inline ALboolean CompExchangePtr(void *volatile*dest, void *oldval, void *newval) +{ + void *ret; + __asm__ __volatile__( +#ifdef __i386__ + "lock; cmpxchgl %2,(%1)" +#else + "lock; cmpxchgq %2,(%1)" +#endif + : "=a" (ret) + : "r" (dest), "r" (newval), "0" (oldval) + : "memory" + ); + return ret == oldval; +} + #elif defined(_WIN32) typedef LONG RefCount; |