Added atomicFetchAndAddsat/Subsat.

This commit is contained in:
Branimir Karadžić
2017-10-23 08:27:03 -07:00
parent 0a2c440a77
commit b6a01bf42c
6 changed files with 104 additions and 6 deletions

View File

@@ -44,6 +44,14 @@ namespace bx
///
void xchg(void* _a, void* _b, size_t _numBytes);
///
template<typename Ty>
Ty min(const Ty& _a, const Ty& _b);
///
template<typename Ty>
Ty max(const Ty& _a, const Ty& _b);
// http://cnicholson.net/2011/01/stupid-c-tricks-a-better-sizeof_array/
template<typename T, size_t N>
char (&COUNTOF_REQUIRES_ARRAY_ARGUMENT(const T(&)[N]) )[N];

View File

@@ -50,6 +50,14 @@ namespace bx
template<typename Ty>
Ty atomicFetchTestAndSub(volatile Ty* _ptr, Ty _test, Ty _value);
///
template<typename Ty>
Ty atomicFetchAndAddsat(volatile Ty* _ptr, Ty _value, Ty _max);
///
template<typename Ty>
Ty atomicFetchAndSubsat(volatile Ty* _ptr, Ty _value, Ty _min);
///
void* atomicExchangePtr(void** _ptr, void* _new);

View File

@@ -32,4 +32,16 @@ namespace bx
Ty tmp = _a; _a = _b; _b = tmp;
}
template<typename Ty>
inline Ty min(const Ty& _a, const Ty& _b)
{
return _a < _b ? _a : _b;
}
template<typename Ty>
inline Ty max(const Ty& _a, const Ty& _b)
{
return _a > _b ? _a : _b;
}
} // namespace bx

View File

@@ -290,6 +290,36 @@ namespace bx
return oldVal;
}
template<typename Ty>
Ty atomicFetchAndAddsat(volatile Ty* _ptr, Ty _value, Ty _max)
{
Ty oldVal;
Ty newVal = *_ptr;
do
{
oldVal = newVal;
newVal = atomicCompareAndSwap<Ty>(_ptr, oldVal, newVal >= _max ? _max : min(_max, newVal+_value) );
} while (oldVal != newVal && oldVal != _max);
return oldVal;
}
template<typename Ty>
Ty atomicFetchAndSubsat(volatile Ty* _ptr, Ty _value, Ty _min)
{
Ty oldVal;
Ty newVal = *_ptr;
do
{
oldVal = newVal;
newVal = atomicCompareAndSwap<Ty>(_ptr, oldVal, newVal <= _min ? _min : max(_min, newVal-_value) );
} while (oldVal != newVal && oldVal != _min);
return oldVal;
}
inline void* atomicExchangePtr(void** _ptr, void* _new)
{
#if BX_COMPILER_MSVC