00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef BOOST_LOCKFREE_ATOMIC_INT_HPP
00010 #define BOOST_LOCKFREE_ATOMIC_INT_HPP
00011
00012 #include <boost/lockfree/detail/prefix.hpp>
00013 #include <boost/lockfree/detail/cas.hpp>
00014 #include <boost/noncopyable.hpp>
00015
00016 namespace boost
00017 {
00018 namespace lockfree
00019 {
00020
00021 #if defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) ) || __INTEL_COMPILER
00022
00023 template <typename T>
00024 class atomic_int:
00025 boost::noncopyable
00026 {
00027 public:
00028 explicit atomic_int(T v = 0):
00029 value(v)
00030 {}
00031
00032 operator T(void) const
00033 {
00034 return __sync_fetch_and_add(&value, 0);
00035 }
00036
00037 void operator =(T v)
00038 {
00039 value = v;
00040 __sync_synchronize();
00041 }
00042
00043 T operator +=(T v)
00044 {
00045 return __sync_add_and_fetch(&value, v);
00046 }
00047
00048 T operator -=(T v)
00049 {
00050 return __sync_sub_and_fetch(&value, v);
00051 }
00052
00053
00054 T operator ++(void)
00055 {
00056 return __sync_add_and_fetch(&value, 1);
00057 }
00058
00059
00060 T operator --(void)
00061 {
00062 return __sync_sub_and_fetch(&value, 1);
00063 }
00064
00065
00066 T operator ++(int)
00067 {
00068 return __sync_fetch_and_add(&value, 1);
00069 }
00070
00071
00072 T operator --(int)
00073 {
00074 return __sync_fetch_and_sub(&value, 1);
00075 }
00076
00077 private:
00078 mutable T value;
00079 };
00080
00081 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
00082
00083 template <typename T>
00084 class atomic_int:
00085 boost::noncopyable
00086 {
00087 public:
00088 explicit atomic_int(T v = 0):
00089 value(v)
00090 {}
00091
00092 operator T(void) const
00093 {
00094 return __gnu_cxx::__exchange_and_add(&value, 0);
00095 }
00096
00097 void operator =(T v)
00098 {
00099 value = v;
00100 }
00101
00102 T operator +=(T v)
00103 {
00104 return __gnu_cxx::__exchange_and_add(&value, v) + v;
00105 }
00106
00107 T operator -=(T v)
00108 {
00109 return __gnu_cxx::__exchange_and_add(&value, -v) - v;
00110 }
00111
00112
00113 T operator ++(void)
00114 {
00115 return operator+=(1);
00116 }
00117
00118
00119 T operator --(void)
00120 {
00121 return operator-=(1);
00122 }
00123
00124
00125 T operator ++(int)
00126 {
00127 return __gnu_cxx::__exchange_and_add(&value, 1);
00128 }
00129
00130
00131 T operator --(int)
00132 {
00133 return __gnu_cxx::__exchange_and_add(&value, -1);
00134 }
00135
00136 private:
00137 mutable _Atomic_word value;
00138 };
00139
00140 #else
00141
00142 template <typename T>
00143 class atomic_int:
00144 boost::noncopyable
00145 {
00146 public:
00147 explicit atomic_int(T v = 0)
00148 {
00149 *this = v;
00150 }
00151
00152 operator T(void) const
00153 {
00154 memory_barrier();
00155 return value;
00156 }
00157
00158 void operator =(T v)
00159 {
00160 value = v;
00161 memory_barrier();
00162 }
00163
00164
00165 T operator ++()
00166 {
00167 return *this += 1;
00168 }
00169
00170
00171 T operator --()
00172 {
00173 return *this -= 1;
00174 }
00175
00176 T operator +=(T v)
00177 {
00178 for(;;)
00179 {
00180 T oldv = value;
00181 T newv = oldv + v;
00182 if(likely(atomic_cas(&value, oldv, newv)))
00183 return newv;
00184 }
00185 }
00186
00187 T operator -=(T v)
00188 {
00189 for(;;)
00190 {
00191 T oldv = value;
00192 T newv = oldv - v;
00193
00194 if(likely(atomic_cas(&value, oldv, newv)))
00195 return newv;
00196 }
00197 }
00198
00199
00200 T operator ++(int)
00201 {
00202 for(;;)
00203 {
00204 T oldv = value;
00205 if(likely(atomic_cas(&value, oldv, oldv+1)))
00206 return oldv;
00207 }
00208 }
00209
00210
00211 T operator --(int)
00212 {
00213 for(;;)
00214 {
00215 T oldv = value;
00216 if(likely(atomic_cas(&value, oldv, oldv-1)))
00217 return oldv;
00218 }
00219 }
00220
00221 private:
00222 T value;
00223 };
00224
00225
00226 #endif
00227
00228 }
00229 }
00230
00231 #endif