mirror of
https://github.com/love2d/megasource.git
synced 2026-08-17 11:11:35 +02:00
Added missing changes to the OpenAL-Soft update.
This commit is contained in:
@@ -8,74 +8,81 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *volatile XchgPtr;
|
||||
|
||||
/* Atomics using C11 */
|
||||
#ifdef HAVE_C11_ATOMIC
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
inline int ExchangeInt(volatile int *ptr, int newval)
|
||||
{ return atomic_exchange(ptr, newval); }
|
||||
inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{ return atomic_exchange(ptr, newval); }
|
||||
#define almemory_order memory_order
|
||||
#define almemory_order_relaxed memory_order_relaxed
|
||||
#define almemory_order_consume memory_order_consume
|
||||
#define almemory_order_acquire memory_order_acquire
|
||||
#define almemory_order_release memory_order_release
|
||||
#define almemory_order_acq_rel memory_order_acq_rel
|
||||
#define almemory_order_seq_cst memory_order_seq_cst
|
||||
|
||||
#define ATOMIC(T) T _Atomic
|
||||
|
||||
#define ATOMIC(T) struct { T _Atomic value; }
|
||||
#define ATOMIC_INIT(_val, _newval) atomic_init((_val), (_newval))
|
||||
#define ATOMIC_INIT_STATIC(_newval) ATOMIC_VAR_INIT(_newval)
|
||||
|
||||
#define ATOMIC_INIT(_val, _newval) atomic_init(&(_val)->value, (_newval))
|
||||
#define ATOMIC_INIT_STATIC(_newval) {ATOMIC_VAR_INIT(_newval)}
|
||||
#define PARAM2(f, a, b, ...) (f((a), (b)))
|
||||
#define PARAM3(f, a, b, c, ...) (f((a), (b), (c)))
|
||||
#define PARAM5(f, a, b, c, d, e, ...) (f((a), (b), (c), (d), (e)))
|
||||
|
||||
#define ATOMIC_LOAD(_val) atomic_load(&(_val)->value)
|
||||
#define ATOMIC_STORE(_val, _newval) atomic_store(&(_val)->value, (_newval))
|
||||
#define ATOMIC_LOAD(...) PARAM2(atomic_load_explicit, __VA_ARGS__, memory_order_seq_cst)
|
||||
#define ATOMIC_STORE(...) PARAM3(atomic_store_explicit, __VA_ARGS__, memory_order_seq_cst)
|
||||
|
||||
#define ATOMIC_ADD(T, _val, _incr) atomic_fetch_add(&(_val)->value, (_incr))
|
||||
#define ATOMIC_SUB(T, _val, _decr) atomic_fetch_sub(&(_val)->value, (_decr))
|
||||
#define ATOMIC_ADD(T, ...) PARAM3(atomic_fetch_add_explicit, __VA_ARGS__, memory_order_seq_cst)
|
||||
#define ATOMIC_SUB(T, ...) PARAM3(atomic_fetch_sub_explicit, __VA_ARGS__, memory_order_seq_cst)
|
||||
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval) atomic_exchange(&(_val)->value, (_newval))
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) \
|
||||
atomic_compare_exchange_strong(&(_val)->value, (_oldval), (_newval))
|
||||
#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _oldval, _newval) \
|
||||
atomic_compare_exchange_weak(&(_val)->value, (_oldval), (_newval))
|
||||
#define ATOMIC_EXCHANGE(T, ...) PARAM3(atomic_exchange_explicit, __VA_ARGS__, memory_order_seq_cst)
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, ...) \
|
||||
PARAM5(atomic_compare_exchange_strong_explicit, __VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst)
|
||||
#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, ...) \
|
||||
PARAM5(atomic_compare_exchange_weak_explicit, __VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst)
|
||||
|
||||
/* Atomics using GCC intrinsics */
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__QNXNTO__)
|
||||
|
||||
inline int ExchangeInt(volatile int *ptr, int newval)
|
||||
{ return __sync_lock_test_and_set(ptr, newval); }
|
||||
inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{ return __sync_lock_test_and_set(ptr, newval); }
|
||||
|
||||
enum almemory_order {
|
||||
almemory_order_relaxed,
|
||||
almemory_order_consume,
|
||||
almemory_order_acquire,
|
||||
almemory_order_release,
|
||||
almemory_order_acq_rel,
|
||||
almemory_order_seq_cst
|
||||
};
|
||||
|
||||
#define ATOMIC(T) struct { T volatile value; }
|
||||
|
||||
#define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0)
|
||||
#define ATOMIC_INIT_STATIC(_newval) {(_newval)}
|
||||
|
||||
#define ATOMIC_LOAD(_val) __extension__({ \
|
||||
#define ATOMIC_LOAD(_val, ...) __extension__({ \
|
||||
__typeof((_val)->value) _r = (_val)->value; \
|
||||
__asm__ __volatile__("" ::: "memory"); \
|
||||
_r; \
|
||||
})
|
||||
#define ATOMIC_STORE(_val, _newval) do { \
|
||||
__asm__ __volatile__("" ::: "memory"); \
|
||||
(_val)->value = (_newval); \
|
||||
#define ATOMIC_STORE(_val, _newval, ...) do { \
|
||||
__asm__ __volatile__("" ::: "memory"); \
|
||||
(_val)->value = (_newval); \
|
||||
} while(0)
|
||||
|
||||
#define ATOMIC_ADD(T, _val, _incr) __extension__({ \
|
||||
#define ATOMIC_ADD(T, _val, _incr, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
__sync_fetch_and_add(&(_val)->value, (_incr)); \
|
||||
})
|
||||
#define ATOMIC_SUB(T, _val, _decr) __extension__({ \
|
||||
#define ATOMIC_SUB(T, _val, _decr, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
__sync_fetch_and_sub(&(_val)->value, (_decr)); \
|
||||
})
|
||||
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval) __extension__({ \
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
__sync_lock_test_and_set(&(_val)->value, (_newval)); \
|
||||
})
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) __extension__({ \
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
T _o = *(_oldval); \
|
||||
*(_oldval) = __sync_val_compare_and_swap(&(_val)->value, _o, (_newval)); \
|
||||
@@ -112,41 +119,38 @@ inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
)
|
||||
|
||||
|
||||
inline int ExchangeInt(volatile int *dest, int newval)
|
||||
{ int ret; WRAP_XCHG("l", ret, dest, newval); return ret; }
|
||||
|
||||
#ifdef __i386__
|
||||
inline void *ExchangePtr(XchgPtr *dest, void *newval)
|
||||
{ void *ret; WRAP_XCHG("l", ret, dest, newval); return ret; }
|
||||
#else
|
||||
inline void *ExchangePtr(XchgPtr *dest, void *newval)
|
||||
{ void *ret; WRAP_XCHG("q", ret, dest, newval); return ret; }
|
||||
#endif
|
||||
|
||||
enum almemory_order {
|
||||
almemory_order_relaxed,
|
||||
almemory_order_consume,
|
||||
almemory_order_acquire,
|
||||
almemory_order_release,
|
||||
almemory_order_acq_rel,
|
||||
almemory_order_seq_cst
|
||||
};
|
||||
|
||||
#define ATOMIC(T) struct { T volatile value; }
|
||||
|
||||
#define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0)
|
||||
#define ATOMIC_INIT_STATIC(_newval) {(_newval)}
|
||||
|
||||
#define ATOMIC_LOAD(_val) __extension__({ \
|
||||
#define ATOMIC_LOAD(_val, ...) __extension__({ \
|
||||
__typeof((_val)->value) _r = (_val)->value; \
|
||||
__asm__ __volatile__("" ::: "memory"); \
|
||||
_r; \
|
||||
})
|
||||
#define ATOMIC_STORE(_val, _newval) do { \
|
||||
__asm__ __volatile__("" ::: "memory"); \
|
||||
(_val)->value = (_newval); \
|
||||
#define ATOMIC_STORE(_val, _newval, ...) do { \
|
||||
__asm__ __volatile__("" ::: "memory"); \
|
||||
(_val)->value = (_newval); \
|
||||
} while(0)
|
||||
|
||||
#define ATOMIC_ADD(T, _val, _incr) __extension__({ \
|
||||
#define ATOMIC_ADD(T, _val, _incr, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==4, "Type "#T" has incorrect size!"); \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
T _r; \
|
||||
WRAP_ADD(_r, &(_val)->value, (T)(_incr)); \
|
||||
_r; \
|
||||
})
|
||||
#define ATOMIC_SUB(T, _val, _decr) __extension__({ \
|
||||
#define ATOMIC_SUB(T, _val, _decr, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==4, "Type "#T" has incorrect size!"); \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
T _r; \
|
||||
@@ -154,7 +158,7 @@ inline void *ExchangePtr(XchgPtr *dest, void *newval)
|
||||
_r; \
|
||||
})
|
||||
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval) __extension__({ \
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
T _r; \
|
||||
@@ -162,7 +166,7 @@ inline void *ExchangePtr(XchgPtr *dest, void *newval)
|
||||
else if(sizeof(T) == 8) WRAP_XCHG("q", _r, &(_val)->value, (T)(_newval)); \
|
||||
_r; \
|
||||
})
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) __extension__({ \
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) __extension__({ \
|
||||
static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \
|
||||
static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \
|
||||
T _old = *(_oldval); \
|
||||
@@ -222,42 +226,40 @@ inline bool CompareAndSwap64(volatile LONGLONG *dest, LONGLONG newval, LONGLONG
|
||||
#define WRAP_XCHG(T, _func, _ptr, _newval) ((T(*)(T volatile*,T))_func)((_ptr), (_newval))
|
||||
#define WRAP_CMPXCHG(T, _func, _ptr, _newval, _oldval) ((bool(*)(T volatile*,T,T*))_func)((_ptr), (_newval), (_oldval))
|
||||
|
||||
inline int ExchangeInt(volatile int *ptr, int newval)
|
||||
{ return WRAP_XCHG(int,AtomicSwap32,ptr,newval); }
|
||||
|
||||
#ifdef _WIN64
|
||||
inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{ return WRAP_XCHG(void*,AtomicSwap64,ptr,newval); }
|
||||
#else
|
||||
inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{ return WRAP_XCHG(void*,AtomicSwap32,ptr,newval); }
|
||||
#endif
|
||||
|
||||
enum almemory_order {
|
||||
almemory_order_relaxed,
|
||||
almemory_order_consume,
|
||||
almemory_order_acquire,
|
||||
almemory_order_release,
|
||||
almemory_order_acq_rel,
|
||||
almemory_order_seq_cst
|
||||
};
|
||||
|
||||
#define ATOMIC(T) struct { T volatile value; }
|
||||
|
||||
#define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0)
|
||||
#define ATOMIC_INIT_STATIC(_newval) {(_newval)}
|
||||
|
||||
#define ATOMIC_LOAD(_val) ((_val)->value)
|
||||
#define ATOMIC_STORE(_val, _newval) do { \
|
||||
(_val)->value = (_newval); \
|
||||
#define ATOMIC_LOAD(_val, ...) ((_val)->value)
|
||||
#define ATOMIC_STORE(_val, _newval, ...) do { \
|
||||
(_val)->value = (_newval); \
|
||||
} while(0)
|
||||
|
||||
int _al_invalid_atomic_size(); /* not defined */
|
||||
|
||||
#define ATOMIC_ADD(T, _val, _incr) \
|
||||
#define ATOMIC_ADD(T, _val, _incr, ...) \
|
||||
((sizeof(T)==4) ? WRAP_ADDSUB(T, AtomicAdd32, &(_val)->value, (_incr)) : \
|
||||
(T)_al_invalid_atomic_size())
|
||||
#define ATOMIC_SUB(T, _val, _decr) \
|
||||
#define ATOMIC_SUB(T, _val, _decr, ...) \
|
||||
((sizeof(T)==4) ? WRAP_ADDSUB(T, AtomicSub32, &(_val)->value, (_decr)) : \
|
||||
(T)_al_invalid_atomic_size())
|
||||
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval) \
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval, ...) \
|
||||
((sizeof(T)==4) ? WRAP_XCHG(T, AtomicSwap32, &(_val)->value, (_newval)) : \
|
||||
(sizeof(T)==8) ? WRAP_XCHG(T, AtomicSwap64, &(_val)->value, (_newval)) : \
|
||||
(T)_al_invalid_atomic_size())
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) \
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) \
|
||||
((sizeof(T)==4) ? WRAP_CMPXCHG(T, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \
|
||||
(sizeof(T)==8) ? WRAP_CMPXCHG(T, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \
|
||||
(bool)_al_invalid_atomic_size())
|
||||
@@ -273,26 +275,22 @@ int _al_invalid_atomic_size(); /* not defined */
|
||||
#define ATOMIC_LOAD_UNSAFE(_val) (0)
|
||||
#define ATOMIC_STORE_UNSAFE(_val, _newval) ((void)0)
|
||||
|
||||
#define ATOMIC_LOAD(_val) (0)
|
||||
#define ATOMIC_STORE(_val, _newval) ((void)0)
|
||||
#define ATOMIC_LOAD(_val, ...) (0)
|
||||
#define ATOMIC_STORE(_val, _newval, ...) ((void)0)
|
||||
|
||||
#define ATOMIC_ADD(T, _val, _incr) (0)
|
||||
#define ATOMIC_SUB(T, _val, _decr) (0)
|
||||
#define ATOMIC_ADD(T, _val, _incr, ...) (0)
|
||||
#define ATOMIC_SUB(T, _val, _decr, ...) (0)
|
||||
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval) (0)
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) (0)
|
||||
#define ATOMIC_EXCHANGE(T, _val, _newval, ...) (0)
|
||||
#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) (0)
|
||||
#endif
|
||||
|
||||
/* If no weak cmpxchg is provided (not all systems will have one), substitute a
|
||||
* strong cmpxchg. */
|
||||
#ifndef ATOMIC_COMPARE_EXCHANGE_WEAK
|
||||
#define ATOMIC_COMPARE_EXCHANGE_WEAK(a, b, c, d) ATOMIC_COMPARE_EXCHANGE_STRONG(a, b, c, d)
|
||||
#define ATOMIC_COMPARE_EXCHANGE_WEAK ATOMIC_COMPARE_EXCHANGE_STRONG
|
||||
#endif
|
||||
|
||||
/* This is *NOT* atomic, but is a handy utility macro to compare-and-swap non-
|
||||
* atomic variables. */
|
||||
#define COMPARE_EXCHANGE(_val, _oldval, _newval) ((*(_val) == *(_oldval)) ? ((*(_val)=(_newval)),true) : ((*(_oldval)=*(_val)),false))
|
||||
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef ATOMIC(uint) RefCount;
|
||||
@@ -306,6 +304,29 @@ inline uint IncrementRef(RefCount *ptr)
|
||||
inline uint DecrementRef(RefCount *ptr)
|
||||
{ return ATOMIC_SUB(uint, ptr, 1)-1; }
|
||||
|
||||
|
||||
/* NOTE: Not atomic! */
|
||||
inline int ExchangeInt(volatile int *ptr, int newval)
|
||||
{
|
||||
int old = *ptr;
|
||||
*ptr = newval;
|
||||
return old;
|
||||
}
|
||||
|
||||
typedef void *volatile XchgPtr;
|
||||
/* NOTE: Not atomic! */
|
||||
inline void *ExchangePtr(XchgPtr *ptr, void *newval)
|
||||
{
|
||||
void *old = *ptr;
|
||||
*ptr = newval;
|
||||
return old;
|
||||
}
|
||||
|
||||
/* This is *NOT* atomic, but is a handy utility macro to compare-and-swap non-
|
||||
* atomic variables. */
|
||||
#define COMPARE_EXCHANGE(_val, _oldval, _newval) ((*(_val) == *(_oldval)) ? ((*(_val)=(_newval)),true) : ((*(_oldval)=*(_val)),false))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user