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 __APPLE__
00021 #include <libkern/OSAtomic.h>
00022 #elif defined __GNUG__
00023 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00024 #include <bits/atomicity.h>
00025 #endif
00026 #else
00027 #error unknown platform
00028 #endif
00029
00030 LT_BEGIN_LIDAR_NAMESPACE
00031
00032 #if defined _WIN32
00033
00034 typedef LONG AtomicInt;
00035
00036 inline AtomicInt AtomicIncrement(AtomicInt &value)
00037 {
00038 return ::InterlockedIncrement(&value);
00039 }
00040
00041 inline AtomicInt AtomicDecrement(AtomicInt &value)
00042 {
00043 return ::InterlockedDecrement(&value);
00044 }
00045
00046 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00047 {
00048 return InterlockedCompareExchangePointer(reinterpret_cast<void **>(&value), newValue, oldValue) == oldValue;
00049 }
00050
00051 #elif defined __APPLE__
00052
00053 typedef int32_t AtomicInt;
00054
00055 inline AtomicInt AtomicIncrement(AtomicInt &value)
00056 {
00057 return OSAtomicIncrement32Barrier(&value);
00058 }
00059
00060 inline AtomicInt AtomicDecrement(AtomicInt &value)
00061 {
00062 return OSAtomicDecrement32Barrier(&value);
00063 }
00064
00065 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00066 {
00067 return ::OSAtomicCompareAndSwapPtrBarrier(oldValue, newValue, reinterpret_cast<void **>(&value));
00068 }
00069
00070
00071 #elif defined __GNUG__
00072
00073 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00074 typedef _Atomic_word AtomicInt;
00075 #else
00076 typedef int AtomicInt;
00077 #endif
00078
00079 inline AtomicInt AtomicIncrement(AtomicInt &value)
00080 {
00081 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00082 return __exchange_and_add(&value, 1) + 1;
00083 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00084 return __gnu_cxx::__exchange_and_add(&value, 1) + 1;
00085 #else
00086 return __sync_add_and_fetch(&value, 1);
00087 #endif
00088 }
00089
00090 inline AtomicInt AtomicDecrement(AtomicInt &value)
00091 {
00092 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00093 return __exchange_and_add(&value, -1) - 1;
00094 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00095 return __gnu_cxx::__exchange_and_add(&value, -1) - 1;
00096 #else
00097 return __sync_sub_and_fetch(&value, 1);
00098 #endif
00099 }
00100
00101 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00102 {
00103 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00104
00105 if(value == oldValue)
00106 {
00107 value = newValue;
00108 return true;
00109 }
00110 else
00111 return false;
00112 #else
00113 return __sync_bool_compare_and_swap(&value, oldValue, newValue);
00114 #endif
00115 }
00116
00117 #else
00118 #error
00119 #endif
00120
00121 LT_END_LIDAR_NAMESPACE
00122 #endif // __LIDAR_ATOMIC_H__