Orocos Real-Time Toolkit  2.6.0
oro_arch.h
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