oro_msvc/oro_arch.h
Go to the documentation of this file.00001
00002 #ifndef __ARCH_MSVC_ORO_ATOMIC__
00003 #define __ARCH_MSVC_ORO_ATOMIC__
00004
00005 #include <windows.h>
00006 #undef interface
00007 #include <intrin.h>
00008
00009 typedef volatile long oro_atomic_t;
00010
00011 #define ORO_ATOMIC_SETUP oro_atomic_set
00012 #define ORO_ATOMIC_CLEANUP(a_int)
00013
00014 #define oro_atomic_read(a_int) (*(a_int))
00015
00016 #define oro_atomic_set(a_int,n) (*(a_int) = (n))
00017
00018 static __forceinline void oro_atomic_add(oro_atomic_t *a_int, int n)
00019 {
00020 _InterlockedExchangeAdd((long *)a_int, n);
00021 }
00022
00023 static __forceinline void oro_atomic_sub(oro_atomic_t *a_int, int n)
00024 {
00025 oro_atomic_add(a_int, -n);
00026 }
00027
00028 static __forceinline int oro_atomic_sub_and_test(oro_atomic_t *a_int, int n)
00029 {
00030 return ((_InterlockedExchangeAdd((long *)a_int, -n) - n) == 0);
00031 }
00032
00033 static __forceinline void oro_atomic_inc(oro_atomic_t *a_int)
00034 {
00035 _InterlockedIncrement((long *)a_int);
00036 }
00037
00038 static __forceinline void oro_atomic_dec(oro_atomic_t *a_int)
00039 {
00040 _InterlockedDecrement((long *)a_int);
00041 }
00042
00043 static __forceinline int oro_atomic_dec_and_test(oro_atomic_t *a_int)
00044 {
00045 return (_InterlockedDecrement((long *)a_int) == 0);
00046 }
00047
00048 static __forceinline int oro_atomic_inc_and_test(oro_atomic_t *a_int)
00049 {
00050 return (_InterlockedIncrement((long *)a_int) == 0);
00051 }
00052
00053 static __forceinline int oro_atomic_add_negative(oro_atomic_t *a_int, int n)
00054 {
00055 return ((_InterlockedExchangeAdd((long *)a_int, n) + n) < 0);
00056 }
00057
00058 static __forceinline int oro_atomic_add_return(oro_atomic_t *a_int, int n)
00059 {
00060 return _InterlockedExchangeAdd((long *)a_int, n) + n;
00061 }
00062
00063 static __forceinline int oro_atomic_sub_return(oro_atomic_t *a_int, int n)
00064 {
00065 return oro_atomic_add_return(a_int, -n);
00066 }
00067
00068 static __forceinline int oro_atomic_inc_return(oro_atomic_t *a_int)
00069 {
00070 return _InterlockedIncrement((long *)a_int);
00071 }
00072
00073 static __forceinline int oro_atomic_dec_return(oro_atomic_t *a_int)
00074 {
00075 return _InterlockedDecrement((long *)a_int);
00076 }
00077
00078 static __forceinline int oro_atomic_clear_mask(oro_atomic_t *a_int, int mask)
00079 {
00080 return _InterlockedAnd((long *)a_int, ~mask);
00081 }
00082
00083 static __forceinline int oro_atomic_set_mask(oro_atomic_t *a_int, int mask)
00084 {
00085 return _InterlockedOr((long *)a_int, mask);
00086 }
00087
00088 #pragma warning(push)
00089 #pragma warning(disable : 4715) // Disable warning on "specified function can potentially not return a value"
00090
00091 template<typename T> inline T oro_cmpxchg(volatile void * ptr, T old, T _new)
00092 {
00093 switch(sizeof(T))
00094 {
00095 case 2:
00096 return (T)(_InterlockedCompareExchange16((short *)ptr, (short)_new, (short)old));
00097 case 4:
00098 return (T)(_InterlockedCompareExchange((long *)ptr, (long)_new, (long)old));
00099 case 8:
00100 return (T)(_InterlockedCompareExchange64((__int64 *)ptr, (__int64)_new, (__int64)old));
00101 }
00102 }
00103
00104 #pragma warning(pop)
00105
00106 #endif