diff --git a/include/bx/cpu.h b/include/bx/cpu.h index cdaa8f7..fcf00d2 100644 --- a/include/bx/cpu.h +++ b/include/bx/cpu.h @@ -76,7 +76,11 @@ namespace bx #endif // BX_COMPILER } - inline int32_t atomicFetchAndAdd(volatile int32_t* _ptr, int32_t _add) + template + inline Ty atomicFetchAndAdd(volatile Ty* _ptr, Ty _value); + + template<> + inline int32_t atomicFetchAndAdd(volatile int32_t* _ptr, int32_t _add) { #if BX_COMPILER_MSVC return _InterlockedExchangeAdd( (volatile long*)_ptr, _add); @@ -85,7 +89,33 @@ namespace bx #endif // BX_COMPILER_ } - inline int32_t atomicAddAndFetch(volatile int32_t* _ptr, int32_t _add) + template<> + inline int64_t atomicFetchAndAdd(volatile int64_t* _ptr, int64_t _add) + { +#if BX_COMPILER_MSVC + return _InterlockedExchangeAdd64( (volatile int64_t*)_ptr, _add); +#else + return __sync_fetch_and_add(_ptr, _add); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicFetchAndAdd(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicFetchAndAdd( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline uint64_t atomicFetchAndAdd(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicFetchAndAdd( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + template + inline Ty atomicAddAndFetch(volatile Ty* _ptr, Ty _value); + + template<> + inline int32_t atomicAddAndFetch(volatile int32_t* _ptr, int32_t _add) { #if BX_COMPILER_MSVC return atomicFetchAndAdd(_ptr, _add) + _add; @@ -94,7 +124,33 @@ namespace bx #endif // BX_COMPILER_ } - inline int32_t atomicFetchAndSub(volatile int32_t* _ptr, int32_t _sub) + template<> + inline int64_t atomicAddAndFetch(volatile int64_t* _ptr, int64_t _add) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, _add) + _add; +#else + return __sync_add_and_fetch(_ptr, _add); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicAddAndFetch(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicAddAndFetch( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline uint64_t atomicAddAndFetch(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicAddAndFetch( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + template + inline Ty atomicFetchAndSub(volatile Ty* _ptr, Ty _value); + + template<> + inline int32_t atomicFetchAndSub(volatile int32_t* _ptr, int32_t _sub) { #if BX_COMPILER_MSVC return atomicFetchAndAdd(_ptr, -_sub); @@ -103,7 +159,33 @@ namespace bx #endif // BX_COMPILER_ } - inline int32_t atomicSubAndFetch(volatile int32_t* _ptr, int32_t _sub) + template<> + inline int64_t atomicFetchAndSub(volatile int64_t* _ptr, int64_t _sub) + { +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, -_sub); +#else + return __sync_fetch_and_sub(_ptr, _sub); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicFetchAndSub(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicFetchAndSub( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline uint64_t atomicFetchAndSub(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicFetchAndSub( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + template + inline Ty atomicSubAndFetch(volatile Ty* _ptr, Ty _value); + + template<> + inline int32_t atomicSubAndFetch(volatile int32_t* _ptr, int32_t _sub) { #if BX_COMPILER_MSVC return atomicFetchAndAdd(_ptr, -_sub) - _sub; @@ -112,16 +194,40 @@ namespace bx #endif // BX_COMPILER_ } - /// Returns the resulting incremented value. - inline int32_t atomicInc(volatile int32_t* _ptr) + template<> + inline int64_t atomicSubAndFetch(volatile int64_t* _ptr, int64_t _sub) { - return atomicAddAndFetch(_ptr, 1); +#if BX_COMPILER_MSVC + return atomicFetchAndAdd(_ptr, -_sub) - _sub; +#else + return __sync_sub_and_fetch(_ptr, _sub); +#endif // BX_COMPILER_ + } + + template<> + inline uint32_t atomicSubAndFetch(volatile uint32_t* _ptr, uint32_t _add) + { + return uint32_t(atomicSubAndFetch( (volatile int32_t*)_ptr, int32_t(_add) ) ); + } + + template<> + inline uint64_t atomicSubAndFetch(volatile uint64_t* _ptr, uint64_t _add) + { + return uint64_t(atomicSubAndFetch( (volatile int64_t*)_ptr, int64_t(_add) ) ); + } + + /// Returns the resulting incremented value. + template + inline Ty atomicInc(volatile Ty* _ptr) + { + return atomicAddAndFetch(_ptr, Ty(1) ); } /// Returns the resulting decremented value. - inline int32_t atomicDec(volatile int32_t* _ptr) + template + inline Ty atomicDec(volatile Ty* _ptr) { - return atomicSubAndFetch(_ptr, 1); + return atomicSubAndFetch(_ptr, Ty(1) ); } ///