Commit 4bd3686f authored by Mikael Ronstrom's avatar Mikael Ronstrom

Fix for Windows atomics

parent 432c5487
...@@ -37,19 +37,17 @@ ...@@ -37,19 +37,17 @@
#else #else
C_MODE_START C_MODE_START
/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/ /*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
LONG _InterlockedExchange (LONG volatile *Target,LONG Value);
LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp); LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value); LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target,
LONGLONG Value, LONGLONG Comp);
C_MODE_END C_MODE_END
#pragma intrinsic(_InterlockedExchangeAdd)
#pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedCompareExchange)
#pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedCompareExchange64)
#endif #endif
#define InterlockedExchange _InterlockedExchange
#define InterlockedExchangeAdd _InterlockedExchangeAdd
#define InterlockedCompareExchange _InterlockedCompareExchange #define InterlockedCompareExchange _InterlockedCompareExchange
#define InterlockedCompareExchange64 _InterlockedCompareExchange64
/* /*
No need to do something special for InterlockedCompareExchangePointer No need to do something special for InterlockedCompareExchangePointer
as it is a #define to InterlockedCompareExchange. The same applies to as it is a #define to InterlockedCompareExchange. The same applies to
...@@ -58,33 +56,39 @@ C_MODE_END ...@@ -58,33 +56,39 @@ C_MODE_END
#endif /*_M_IX86*/ #endif /*_M_IX86*/
#define MY_ATOMIC_MODE "msvc-intrinsics" #define MY_ATOMIC_MODE "msvc-intrinsics"
#define IL_EXCHG_ADD32(X,Y) \ /* Implement using CAS on WIN32 */
InterlockedExchangeAdd((volatile LONG *)(X),(Y))
#define IL_EXCHG_ADD64(X,Y) \
InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y))
#define IL_COMP_EXCHG32(X,Y,Z) \ #define IL_COMP_EXCHG32(X,Y,Z) \
InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
#define IL_COMP_EXCHG64(X,Y,Z) \ #define IL_COMP_EXCHG64(X,Y,Z) \
InterlockedCompareExchange64((volatile LONGLONG *)(X), \ InterlockedCompareExchange64((volatile LONGLONG *)(X), \
(LONGLONG)(Y),(LONGLONG)(Z)) (LONGLONG)(Y),(LONGLONG)(Z))
#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer #define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
#define make_atomic_cas_body(S) \
int ## S initial_cmp= *cmp; \
int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
#ifndef _M_IX86
/* Use full set of optimised functions on WIN64 */
#define IL_EXCHG_ADD32(X,Y) \
InterlockedExchangeAdd((volatile LONG *)(X),(Y))
#define IL_EXCHG_ADD64(X,Y) \
InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y))
#define IL_EXCHG32(X,Y) \ #define IL_EXCHG32(X,Y) \
InterlockedExchange((volatile LONG *)(X),(Y)) InterlockedExchange((volatile LONG *)(X),(Y))
#define IL_EXCHG64(X,Y) \ #define IL_EXCHG64(X,Y) \
InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y)) InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y))
#define IL_EXCHGptr InterlockedExchangePointer #define IL_EXCHGptr InterlockedExchangePointer
#define make_atomic_add_body(S) \ #define make_atomic_add_body(S) \
v= IL_EXCHG_ADD ## S (a, v) v= IL_EXCHG_ADD ## S (a, v)
#define make_atomic_cas_body(S) \
int ## S initial_cmp= *cmp; \
int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
#define make_atomic_swap_body(S) \ #define make_atomic_swap_body(S) \
v= IL_EXCHG ## S (a, v) v= IL_EXCHG ## S (a, v)
#define make_atomic_load_body(S) \ #define make_atomic_load_body(S) \
ret= 0; /* avoid compiler warning */ \ ret= 0; /* avoid compiler warning */ \
ret= IL_COMP_EXCHG ## S (a, ret, ret); ret= IL_COMP_EXCHG ## S (a, ret, ret);
#endif
/* /*
my_yield_processor (equivalent of x86 PAUSE instruction) should be used my_yield_processor (equivalent of x86 PAUSE instruction) should be used
to improve performance on hyperthreaded CPUs. Intel recommends to use it in to improve performance on hyperthreaded CPUs. Intel recommends to use it in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment