|
|
@@ -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 int32_t atomicCompareAndSwap(volatile void* _ptr, int32_t _old, int32_t _new)
|
|
|
+ {
|
|
|
+#if BX_COMPILER_MSVC
|
|
|
+ return _InterlockedCompareExchange( (volatile LONG*)(_ptr), _new, _old);
|
|
|
+#else
|
|
|
+ return __sync_val_compare_and_swap(_ptr, _old, _new);
|
|
|
#endif // BX_COMPILER
|
|
|
}
|
|
|
|
|
|
- inline void* atomicExchangePtr(void** _target, void* _ptr)
|
|
|
+ ///
|
|
|
+ inline void* atomicExchangePtr(void** _ptr, void* _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 _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
|