00001
00002
00003
00004
00005
00006
00007
00008
00010
00011
00012 #ifndef __LIDAR_ATOMIC_H__
00013 #define __LIDAR_ATOMIC_H__
00014
00015 #include "lidar/Base.h"
00016
00017 #if defined _WIN32
00018 #define NOMINMAX
00019 #include <windows.h>
00020 #elif defined __GNUG__
00021 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00022 #include <bits/atomicity.h>
00023 #endif
00024 #else
00025 #error unknown platform
00026 #endif
00027
00028 LT_BEGIN_LIDAR_NAMESPACE
00029
00030 #if defined _WIN32
00031
00032 typedef LONG AtomicInt;
00033
00034 inline AtomicInt AtomicIncrement(AtomicInt &value)
00035 {
00036 return ::InterlockedIncrement(&value);
00037 }
00038
00039 inline AtomicInt AtomicDecrement(AtomicInt &value)
00040 {
00041 return ::InterlockedDecrement(&value);
00042 }
00043
00044 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00045 {
00046 return InterlockedCompareExchangePointer(reinterpret_cast<void **>(&value), newValue, oldValue) == oldValue;
00047 }
00048
00049 #elif defined __GNUG__
00050
00051 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00052 typedef _Atomic_word AtomicInt;
00053 #else
00054 typedef int AtomicInt;
00055 #endif
00056
00057 inline AtomicInt AtomicIncrement(AtomicInt &value)
00058 {
00059 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00060 return __exchange_and_add(&value, 1) + 1;
00061 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00062 return __gnu_cxx::__exchange_and_add(&value, 1) + 1;
00063 #else
00064 return __sync_add_and_fetch(&value, 1);
00065 #endif
00066 }
00067
00068 inline AtomicInt AtomicDecrement(AtomicInt &value)
00069 {
00070 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00071 return __exchange_and_add(&value, -1) - 1;
00072 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00073 return __gnu_cxx::__exchange_and_add(&value, -1) - 1;
00074 #else
00075 return __sync_sub_and_fetch(&value, 1);
00076 #endif
00077 }
00078
00079 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00080 {
00081 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00082
00083 if(value == oldValue)
00084 {
00085 value = newValue;
00086 return true;
00087 }
00088 else
00089 return false;
00090 #else
00091 return __sync_bool_compare_and_swap(&value, oldValue, newValue);
00092 #endif
00093 }
00094
00095 #else
00096 #error
00097 #endif
00098
00099 LT_END_LIDAR_NAMESPACE
00100 #endif // __LIDAR_ATOMIC_H__