Added atomicTestAndInc/Dec.

This commit is contained in:
Branimir Karadžić
2014-08-08 22:55:45 -07:00
parent f0fdc33f32
commit aa2d6a90b3

View File

@@ -27,37 +27,43 @@ extern "C" void _ReadWriteBarrier();
# pragma intrinsic(_ReadWriteBarrier)
# pragma intrinsic(_InterlockedIncrement)
# pragma intrinsic(_InterlockedDecrement)
# pragma intrinsic(_InterlockedCompareExchange)
# pragma intrinsic(_InterlockedExchangePointer)
#endif // BX_COMPILER_MSVC
namespace bx
{
///
inline void readBarrier()
{
#if BX_COMPILER_MSVC
_ReadBarrier();
#elif BX_COMPILER_GCC || BX_COMPILER_CLANG
#else
asm volatile("":::"memory");
#endif // BX_COMPILER
}
///
inline void writeBarrier()
{
#if BX_COMPILER_MSVC
_WriteBarrier();
#elif BX_COMPILER_GCC || BX_COMPILER_CLANG
#else
asm volatile("":::"memory");
#endif // BX_COMPILER
}
///
inline void readWriteBarrier()
{
#if BX_COMPILER_MSVC
_ReadWriteBarrier();
#elif BX_COMPILER_GCC || BX_COMPILER_CLANG
#else
asm volatile("":::"memory");
#endif // BX_COMPILER
}
///
inline void memoryBarrier()
{
#if BX_PLATFORM_XBOX360
@@ -72,33 +78,76 @@ namespace bx
#endif // BX_COMPILER
}
inline int32_t atomicIncr(volatile void* _var)
///
inline int32_t atomicInc(volatile void* _ptr)
{
#if BX_COMPILER_MSVC
return _InterlockedIncrement( (volatile LONG*)(_var) );
#elif BX_COMPILER_GCC || BX_COMPILER_CLANG
return __sync_fetch_and_add( (volatile int32_t*)_var, 1);
return _InterlockedIncrement( (volatile LONG*)(_ptr) );
#else
return __sync_fetch_and_add( (volatile int32_t*)_ptr, 1);
#endif // BX_COMPILER
}
inline int32_t atomicDecr(volatile void* _var)
///
inline int32_t atomicDec(volatile void* _ptr)
{
#if BX_COMPILER_MSVC
return _InterlockedDecrement( (volatile LONG*)(_var) );
#elif BX_COMPILER_GCC || BX_COMPILER_CLANG
return __sync_fetch_and_sub( (volatile int32_t*)_var, 1);
return _InterlockedDecrement( (volatile LONG*)(_ptr) );
#else
return __sync_fetch_and_sub( (volatile int32_t*)_ptr, 1);
#endif // BX_COMPILER
}
inline void* atomicExchangePtr(void** _target, void* _ptr)
///
inline int32_t atomicCompareAndSwap(volatile void* _ptr, int32_t _old, int32_t _new)
{
#if BX_COMPILER_MSVC
return InterlockedExchangePointer(_target, _ptr);
#elif BX_COMPILER_GCC || BX_COMPILER_CLANG
return __sync_lock_test_and_set(_target, _ptr);
return _InterlockedCompareExchange( (volatile LONG*)(_ptr), _new, _old);
#else
return __sync_val_compare_and_swap(_ptr, _old, _new);
#endif // BX_COMPILER
}
///
inline void* atomicExchangePtr(void** _ptr, void* _new)
{
#if BX_COMPILER_MSVC
return _InterlockedExchangePointer(_ptr, _new);
#else
return __sync_lock_test_and_set(_ptr, _new);
#endif // BX_COMPILER
}
///
inline int32_t atomicTestAndInc(volatile void* _ptr, int32_t _test)
{
int32_t oldVal;
int32_t newVal = *(int32_t volatile*)_ptr;
do
{
oldVal = newVal;
newVal = atomicCompareAndSwap(_ptr, oldVal, newVal >= _test ? _test : newVal+1);
} while (oldVal != newVal);
return oldVal;
}
///
inline int32_t atomicTestAndDec(volatile void* _ptr, int32_t _test)
{
int32_t oldVal;
int32_t newVal = *(int32_t volatile*)_ptr;
do
{
oldVal = newVal;
newVal = atomicCompareAndSwap(_ptr, oldVal, newVal <= _test ? _test : newVal+1);
} while (oldVal != newVal);
return oldVal;
}
} // namespace bx
#endif // BX_CPU_H_HEADER_GUARD