00001
00008
00009
00010
00011
00012
00013
00014
00015
00019 inline CLASS_METHOD
00020 void
00021 Set( ATOMIC_TYPE* out, ATOMIC_TYPE val )
00022 {
00023 *out = val;
00024 }
00025
00029 inline CLASS_METHOD
00030 ATOMIC_TYPE
00031 Add( ATOMIC_TYPE* sum, ATOMIC_TYPE addend )
00032 {
00033 #if CPU_X86
00034
00035
00036
00037 ATOMIC_TYPE tmp = addend;
00038 asm volatile ( "lock; xadd %0,%1"
00039 : "=r"(tmp), "=m"(*sum)
00040 : "0"(tmp), "m"(*sum)
00041 : "memory", "cc" );
00042 return tmp + addend;
00043 #elif GCC_VERSION >= 40100
00044 return __sync_add_and_fetch( sum, addend );
00045 #elif CPU_PPC
00046
00047
00048
00049 ATOMIC_TYPE tmp;
00050 asm volatile( " sync \n"
00051 "1: lwarx %0,0,%2 \n"
00052 " add %0,%1,%0 \n"
00053 " stwcx. %0,0,%2 \n"
00054 " bne- 1b \n"
00055 " isync \n"
00056 : "=&r" (tmp)
00057 : "r" (addend), "r" (sum)
00058 : "cc", "memory" );
00059 return tmp;
00060 #else
00061 #error
00062 #endif
00063 }
00064
00069 inline CLASS_METHOD
00070 ATOMIC_TYPE
00071 Xchg( ATOMIC_TYPE* ptr, ATOMIC_TYPE val )
00072 {
00073 #if CPU_X86
00074 asm volatile( "xchg %0, %1"
00075 : "=r"(val), "=m"(*(ptr))
00076 : "0"(val), "r"(*(ptr))
00077 );
00078 return val;
00079 #elif GCC_VERSION >= 40100
00080
00081 return __sync_lock_test_and_set( ptr, val );
00082 #elif CPU_PPC
00083 long prev;
00084 asm volatile( " sync \n"
00085 "1: lwarx %0,0,%2 \n"
00086 " stwcx. %3,0,%2 \n"
00087 " bne- 1b \n"
00088 " isync \n"
00089 : "=&r" (prev), "+m" (ptr)
00090 : "r" (ptr), "r" (val)
00091 : "cc", "memory");
00092 return prev;
00093 #else
00094 #error
00095 #endif
00096 }
00097
00098