[llvm-commits] [llvm] r72087 - /llvm/trunk/include/llvm/System/Atomic.h
Sebastian Redl
sebastian.redl at getdesigned.at
Tue May 19 06:59:56 PDT 2009
Owen Anderson wrote:
> Author: resistor
> Date: Mon May 18 20:07:40 2009
> New Revision: 72087
>
> URL: http://llvm.org/viewvc/llvm-project?rev=72087&view=rev
> Log:
> Fix up the Windows portion of Atomic.h. This is untested, but it is my best understanding of what should work.
> I'd be much obliged if someone on MSVC++ could try this out and let me know if it works.
>
> Modified:
> llvm/trunk/include/llvm/System/Atomic.h
>
> Modified: llvm/trunk/include/llvm/System/Atomic.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/System/Atomic.h?rev=72087&r1=72086&r2=72087&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/System/Atomic.h (original)
> +++ llvm/trunk/include/llvm/System/Atomic.h Mon May 18 20:07:40 2009
> @@ -62,11 +62,24 @@
> }
> #elif defined(_MSC_VER)
> typedef LONG cas_flag;
> + template<typename T>
> inline T CompareAndSwap(volatile T* ptr,
> T new_value,
> T old_value) {
> - return InterlockedCompareExchange(addr, new_value, old_value);
> + if (sizeof(T) == 4)
> + return InterlockedCompareExchange(ptr, new_value, old_value);
> + else
> + return InterlockedCompareExchange64(ptr, new_value, old_value);
> }
>
I'm not booted into Windows, but this cannot possibly compile. An if
must have all branches valid even if the condition is a compile-time
constant. You could force some casts, or you could specialize the
function on 4-byte types. Eh, you'll need the casts anyway, because the
WinAPI sucks.
> + else
> + assert(0 && "Unsupported compare-and-swap size!");
>
However, it would be really nice to catch this at compile time.
And another thing, the function is called InterlockedCompareExchangePointer.
The code below is untested, but should do the Right Thing.
template <typename T, size_t N>
struct CompareAndSwapImpl;
template <typename T>
struct CompareAndSwapImpl<T, 4> {
static T DoCAS(volatile T* ptr, T n, T o) {
return InterlockedCompareExchange(reinterpret_cast<LONG
volatile*>(ptr), n, o);
}
}
template <typename T>
struct CompareAndSwapImpl<T, 8> {
static T DoCAS(volatile T* ptr, T n, T o) {
return InterlockedCompareExchange64(reinterpret_cast<LONGLONG
volatile*>(ptr), n, o);
}
}
template <typename T>
struct CompareAndSwapImpl<T*, sizeof(T*)> {
static T DoCAS(T* volatile* ptr, T* n, T* o) {
return InterlockedCompareExchangePointer(reinterpret_cast<void*
volatile*>(ptr), n, o);
}
}
template <typename T>
inline T CompareAndSwap(T volatile *ptr, T new_value, T old_value) {
return CompareAndSwapImpl<T, sizeof(T)>::DoCAS(ptr, new_value, old_value);
}
Sebastian
More information about the llvm-commits
mailing list