Orocos Real-Time Toolkit
2.6.0
|
00001 #include "../../rtt-config.h" 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