huh, InterlockedAdd only exists on win64, weird.

This commit is contained in:
David Rose 2011-11-18 22:33:34 +00:00
parent dca824b5de
commit 82a33fad3e

View File

@ -57,7 +57,10 @@ add(TVOLATILE AtomicAdjustWin32Impl::Integer &var, AtomicAdjustWin32Impl::Intege
#ifdef _WIN64 #ifdef _WIN64
InterlockedAdd64(&var, delta); InterlockedAdd64(&var, delta);
#else #else
InterlockedAdd(&var, delta); AtomicAdjustWin32Impl::Integer orig_value = var;
while (compare_and_exchange(var, orig_value, orig_value + delta) != orig_value) {
orig_value = var;
}
#endif // _WIN64 #endif // _WIN64
} }
@ -89,12 +92,13 @@ set(TVOLATILE AtomicAdjustWin32Impl::Integer &var,
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl:: INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl::
get(const TVOLATILE AtomicAdjustWin32Impl::Integer &var) { get(const TVOLATILE AtomicAdjustWin32Impl::Integer &var) {
// On Intel platforms, word-aligned loads are atomic (if performed
// in a single instruction). We can't guarantee the compiler will
// generate a single instruction to load this value, but it
// certainly won't happen if its address isn't word-aligned, so make
// sure that's the case.
assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0); assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
#ifdef _WIN64 return var;
return InterlockedAdd64((TVOLATILE AtomicAdjustWin32Impl::Integer *)&var, 0);
#else
return InterlockedAdd((TVOLATILE AtomicAdjustWin32Impl::Integer *)&var, 0);
#endif // _WIN64
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -117,12 +121,13 @@ set_ptr(TVOLATILE AtomicAdjustWin32Impl::Pointer &var,
// indicated variable. This is the only guaranteed safe // indicated variable. This is the only guaranteed safe
// way to retrieve the value that other threads might be // way to retrieve the value that other threads might be
// asynchronously setting, incrementing, or decrementing // asynchronously setting, incrementing, or decrementing
// (via other AtomicAdjust methods). // (via other AtomicAjust methods).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustWin32Impl::Pointer AtomicAdjustWin32Impl:: INLINE AtomicAdjustWin32Impl::Pointer AtomicAdjustWin32Impl::
get_ptr(const TVOLATILE AtomicAdjustWin32Impl::Pointer &var) { get_ptr(const TVOLATILE AtomicAdjustWin32Impl::Pointer &var) {
assert(sizeof(Pointer) == sizeof(Integer)); // As in get(), make sure the address is word-aligned.
return (Pointer)get(*(const TVOLATILE Integer *)&var); assert((((size_t)&var) & (sizeof(Pointer) - 1)) == 0);
return var;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////