00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef FXATOMIC_H
00022 #define FXATOMIC_H
00023
00024
00025 namespace FX {
00026
00027
00028
00029
00030
00031 class FXAtomicInt {
00032 private:
00033 volatile FXint val;
00034 public:
00035
00036
00037 FXAtomicInt(FXint v=0):val(v){}
00038
00039
00040
00041 FXAtomicInt& operator=(FXint v){ val=v; return *this; }
00042
00043
00044
00045 operator FXint() const { return val; }
00046
00047
00048
00049 inline FXint get() const { return val; }
00050
00051
00052
00053 inline FXint set(FXint v){
00054 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00055 FXint ret=v;
00056 __asm__ __volatile__("lock\n\t"
00057 "xchgl %0,%1\n\t" : "=r" (ret) : "m" (val), "0" (ret) : "memory");
00058 return ret;
00059 #elif defined(WIN32)
00060 return InterlockedExchange((LONG*)&val,v);
00061 #else
00062 FXint ret=val;
00063 val=v;
00064 return ret;
00065 #endif
00066 }
00067
00068
00069
00070 inline FXint cas(FXint expect,FXint v){
00071 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00072 FXint ret;
00073 __asm__ __volatile__("lock\n\t"
00074 "cmpxchgl %1,%2\n\t" : "=a" (ret) : "r" (v), "m" (val), "0" (expect) : "memory");
00075 return ret;
00076 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00077 return __sync_val_compare_and_swap(&val,expect,v);
00078 #elif defined(WIN32)
00079 return InterlockedCompareExchange((LONG*)&val,v,expect);
00080 #else
00081 FXint ret=val;
00082 if(val==expect) val=v;
00083 return ret;
00084 #endif
00085 }
00086
00087
00088
00089 inline FXAtomicInt& operator+=(FXint v){
00090 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00091 __asm__ __volatile__ ("lock\n\t"
00092 "addl %1,%0\n\t" : "=m" (val) : "ir" (v), "m" (val) : "memory");
00093 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00094 __sync_add_and_fetch(&val,v);
00095 #elif defined(WIN32)
00096 InterlockedAdd((LONG*)&val,v);
00097 #else
00098 val+=v;
00099 #endif
00100 return *this;
00101 }
00102
00103
00104
00105 inline FXAtomicInt& operator-=(FXint v){
00106 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00107 __asm__ __volatile__ ("lock\n\t"
00108 "subl %1,%0\n\t" : "=m" (val) : "ir" (v), "m" (val) : "memory");
00109 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00110 __sync_add_and_fetch(&val,-v);
00111 #elif defined(WIN32)
00112 InterlockedAdd((LONG*)&val,-v);
00113 #else
00114 val-=v;
00115 #endif
00116 return *this;
00117 }
00118
00119
00120
00121 inline FXAtomicInt& operator|=(FXint v){
00122 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00123 __asm__ __volatile__ ("lock\n\t"
00124 "orl %1,%0\n\t" : "=m" (val) : "ir" (v), "m" (val) : "memory");
00125 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00126 __sync_or_and_fetch(&val,v);
00127 #elif defined(WIN32)
00128 InterlockedOr((LONG*)&val,v);
00129 #else
00130 val|=v;
00131 #endif
00132 return *this;
00133 }
00134
00135
00136
00137 inline FXAtomicInt& operator&=(FXint v){
00138 #if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00139 __sync_and_and_fetch(&val,v);
00140 #elif (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00141 __asm__ __volatile__ ("lock\n\t"
00142 "andl %1,%0\n\t" : "=m" (val) : "ir" (v), "m" (val) : "memory");
00143 #elif defined(WIN32)
00144 InterlockedAnd((LONG*)&val,v);
00145 #else
00146 val&=v;
00147 #endif
00148 return *this;
00149 }
00150
00151
00152
00153 inline FXAtomicInt& operator^=(FXint v){
00154 #if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00155 __sync_xor_and_fetch(&val,v);
00156 #elif (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00157 __asm__ __volatile__ ("lock\n\t"
00158 "xorl %1,%0\n\t" : "=m" (val) : "ir" (v), "m" (val) : "memory");
00159 #elif defined(WIN32)
00160 InterlockedXor((LONG*)&val,v);
00161 #else
00162 val^=v;
00163 #endif
00164 return *this;
00165 }
00166
00167
00168
00169 inline FXint operator++(){
00170 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00171 FXint ret=1;
00172 __asm__ __volatile__ ("lock\n\t"
00173 "xaddl %0,%1\n\t" : "=r"(ret), "=m"(val) : "0"(ret), "m"(val) : "memory");
00174 return ret+1;
00175 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00176 return __sync_add_and_fetch(&val,1);
00177 #elif defined(WIN32)
00178 return InterlockedAdd((LONG*)&val,1);
00179 #else
00180 return ++val;
00181 #endif
00182 }
00183
00184
00185
00186 inline FXint operator--(){
00187 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00188 FXint ret=-1;
00189 __asm__ __volatile__ ("lock\n\t"
00190 "xaddl %0,%1\n\t" : "=r"(ret), "=m"(val) : "0"(ret), "m"(val) : "memory");
00191 return ret-1;
00192 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00193 return __sync_add_and_fetch(&val,-1);
00194 #elif defined(WIN32)
00195 return InterlockedAdd((LONG*)&val,-1);
00196 #else
00197 return --val;
00198 #endif
00199 }
00200
00201
00202
00203 inline int operator++(FXint){
00204 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00205 FXint ret=1;
00206 __asm__ __volatile__ ("lock\n\t"
00207 "xaddl %0,%1\n\t" : "=r"(ret), "=m"(val) : "0"(ret), "m"(val) : "memory");
00208 return ret;
00209 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00210 return __sync_fetch_and_add(&val,1);
00211 #elif defined(WIN32)
00212 return InterlockedExchangeAdd((LONG*)&val,1);
00213 #else
00214 return val++;
00215 #endif
00216 }
00217
00218
00219
00220 inline FXint operator--(FXint){
00221 #if (defined(__GNUC__) || defined(__ICC)) && (defined(__i386__) || defined(__x86_64__))
00222 FXint ret=-1;
00223 __asm__ __volatile__ ("lock\n\t"
00224 "xaddl %0,%1\n\t" : "=r"(ret), "=m"(val) : "0"(ret), "m"(val) : "memory");
00225 return ret;
00226 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00227 return __sync_fetch_and_add(&val,-1);
00228 #elif defined(WIN32)
00229 return InterlockedExchangeAdd((LONG*)&val,-1);
00230 #else
00231 return val--;
00232 #endif
00233 }
00234 };
00235
00236
00237
00238
00239
00240
00241
00242 template<class EType>
00243 class FXAtomicPtr {
00244 private:
00245 EType *volatile ptr;
00246 public:
00247
00248
00249 FXAtomicPtr(EType* p=NULL):ptr(p){ }
00250
00251
00252 FXAtomicPtr& operator=(EType *p){ ptr=p; return *this; }
00253
00254
00255 operator EType*() const { return ptr; }
00256
00257
00258 EType& operator*() const { return *ptr; }
00259
00260
00261 EType *operator->() const { return ptr; }
00262
00263
00264
00265 inline EType* get() const { return ptr; }
00266
00267
00268
00269 inline EType* set(EType* p){
00270 #if (defined(__GNUC__) || defined(__ICC)) && defined(__i386__)
00271 EType* ret=p;
00272 __asm__ __volatile__("lock\n\t"
00273 "xchgl %0,%1\n\t" : "=r" (ret) : "m" (ptr), "0" (ret) : "memory");
00274 return ret;
00275 #elif (defined(__GNUC__) || defined(__ICC)) && defined(__x86_64__)
00276 EType* ret=p;
00277 __asm__ __volatile__("lock\n\t"
00278 "xchgq %0,%1\n\t" : "=r" (ret) : "m" (ptr), "0" (ret) : "memory");
00279 return ret;
00280 #elif defined(WIN32)
00281 return (EType*)InterlockedExchangePointer((void *volatile)&ptr,p);
00282 #else
00283 EType* ret=ptr;
00284 ptr=p;
00285 return ret;
00286 #endif
00287 }
00288
00289
00290
00291 inline EType* cas(EType* expect,EType* p){
00292 #if (defined(__GNUC__) || defined(__ICC)) && defined(__i386__)
00293 EType* ret;
00294 __asm__ __volatile__("lock\n\t"
00295 "cmpxchgl %1,%2\n\t" : "=a" (ret) : "r" (p), "m" (ptr), "0" (expect) : "memory");
00296 return ret;
00297 #elif (defined(__GNUC__) || defined(__ICC)) && defined(__x86_64__)
00298 EType* ret;
00299 __asm__ __volatile__("lock\n\t"
00300 "cmpxchgq %1,%2\n\t" : "=a" (ret) : "r" (p), "m" (ptr), "0" (expect) : "memory");
00301 return ret;
00302 #elif defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
00303 return __sync_val_compare_and_swap(&ptr,expect,p);
00304 #elif defined(WIN32)
00305 return (EType*)InterlockedCompareExchangePointer((void *volatile)&ptr,p,expect);
00306 #else
00307 EType* ret=ptr;
00308 if(ptr==expect) ptr=p;
00309 return ret;
00310 #endif
00311 }
00312 };
00313
00314
00315 }
00316
00317 #endif