21 #ifndef __SYS_ATOMICIMPL_H_INCLUDED__
22 #define __SYS_ATOMICIMPL_H_INCLUDED__
32 #define SYS_ATOMIC_INLINE SYS_FORCE_INLINE
34 #define SYS_ATOMIC_INLINE inline
37 #include <libkern/OSAtomic.h>
41 namespace SYS_AtomicImpl
47 "Cannot instantiate test_and_set for unsupported type.");
52 "Cannot instantiate test_and_add for unsupported type.");
57 "Cannot instantiate compare_and_swap for unsupported type.");
61 #if defined(LINUX) || defined(MBSD)
67 #if !SYS_IS_GCC_GE(4, 1)
68 #error "Unsupported gcc version"
75 return __sync_lock_test_and_set(addr,
val);
82 return __sync_fetch_and_add(addr,
val);
88 compare_and_swap<int32>(
volatile int32 *addr,
int32 oldval,
int32 newval)
90 return __sync_val_compare_and_swap(const_cast<int32 *>(addr),oldval,newval);
100 return __sync_lock_test_and_set(addr,
val);
107 return __sync_fetch_and_add(addr,
val);
112 compare_and_swap<int64>(
volatile int64 *addr,
int64 oldval,
int64 newval)
114 return __sync_val_compare_and_swap(const_cast<int64 *>(addr),oldval,newval);
128 #if defined(MBSD_ARM)
129 return __sync_lock_test_and_set(addr,
val);
131 __asm__ __volatile__(
"lock xchgl %0, %1"
132 :
"=r"(oldval),
"=m"(*(addr))
133 :
"0"(
val),
"m"(*(addr)));
142 return __sync_fetch_and_add(addr,
val);
147 compare_and_swap<int32>(
volatile int32 *addr,
int32 oldval,
int32 newval)
149 return __sync_val_compare_and_swap(const_cast<int32 *>(addr),oldval,newval);
156 return __sync_lock_test_and_set(addr,
val);
163 return __sync_fetch_and_add(addr,
val);
168 compare_and_swap<int64>(
volatile int64 *addr,
int64 oldval,
int64 newval)
170 return __sync_val_compare_and_swap(const_cast<int64 *>(addr),oldval,newval);
175 test_and_set<time_t>(time_t *addr, time_t
val)
177 return __sync_lock_test_and_set(addr,
val);
182 test_and_add<time_t>(time_t *addr, time_t
val)
184 return __sync_fetch_and_add(addr,
val);
189 compare_and_swap<time_t>(
volatile time_t *addr, time_t oldval, time_t newval)
191 return __sync_val_compare_and_swap(
192 const_cast<time_t *>(addr),oldval,newval);
195 #endif // defined(LINUX) || defined(MBSD)
197 template <
typename T>
204 *
static_cast<volatile T *
>(addr) = val;
213 __sync_lock_release(&dummy);
219 (
void)__sync_lock_test_and_set(addr, val);
227 *
static_cast<volatile T *
>(addr) = val;
231 template <
typename T>
237 T val = *
static_cast<const volatile T *
>(addr);
244 return __sync_val_compare_and_swap(const_cast<T *>(addr), tmp, tmp);
250 return *
static_cast<const volatile T *
>(addr);
256 #pragma intrinsic (_InterlockedExchange)
257 #pragma intrinsic (_InterlockedExchangeAdd)
258 #pragma intrinsic (_InterlockedCompareExchange)
264 return (
int32)_InterlockedExchange((
long *)addr, (
long)val);
271 return (
int32)_InterlockedExchangeAdd((
long *)addr, (
long)val);
276 compare_and_swap<int32>(
volatile int32 *addr,
int32 oldval,
int32 newval)
278 return _InterlockedCompareExchange((
volatile long *)addr, newval, oldval);
283 #pragma intrinsic (_InterlockedCompareExchange64)
287 compare_and_swap<int64>(
volatile int64 *addr,
int64 oldval,
int64 newval)
289 return _InterlockedCompareExchange64(addr, newval, oldval);
292 #if defined(AMD64) || defined(ARM64)
294 #pragma intrinsic (_InterlockedExchange64)
295 #pragma intrinsic (_InterlockedExchangeAdd64)
301 return _InterlockedExchange64(addr, val);
308 return _InterlockedExchangeAdd64(addr, val);
320 int64 retval = *addr;
323 int64 newretval = _InterlockedCompareExchange64(addr, val, retval);
324 if (retval == newretval)
336 int64 retval = *addr;
339 int64 newretval = _InterlockedCompareExchange64(addr, retval+val, retval);
340 if (retval == newretval)
352 #pragma intrinsic (_ReadBarrier)
353 #pragma intrinsic (_WriteBarrier)
354 #pragma intrinsic (_InterlockedCompareExchange)
356 template <
typename T>
374 *
static_cast<volatile T *
>(addr) = val;
396 template <typename T>
414 return *
static_cast<const volatile T *
>(addr);
439 #error "Unsupported platform"
444 #endif // __SYS_ATOMICIMPL_H_INCLUDED__
T compare_and_swap(volatile T *addr, T oldval, T newval)
#define SYS_STATIC_ASSERT_MSG(expr, msg)
#define SYS_DEPRECATED_PUSH_DISABLE()
#define SYS_DEPRECATED_POP_DISABLE()
T test_and_set(T *addr, T val)
#define SYS_ATOMIC_INLINE
constexpr enabler dummy
An instance to use in EnableIf.
GLdouble GLdouble GLint GLint order
T test_and_add(T *addr, T val)