00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __JackAtomic__
00021 #define __JackAtomic__
00022
00023 typedef unsigned short UInt16;
00024 typedef unsigned long UInt32;
00025 typedef long SInt32;
00026 #ifdef WIN32
00027 #include <windows.h>
00028
00029 typedef ULONGLONG UInt64;
00030 #else
00031
00032 typedef unsigned long long UInt64;
00033 #endif
00034
00035 #if defined(__APPLE__)
00036
00037 #if defined(__ppc__)
00038
00039 static inline int CAS(register UInt32 value, register UInt32 newvalue, register volatile void* addr)
00040 {
00041 register int result;
00042 asm volatile (
00043 "# CAS \n"
00044 " lwarx r0, 0, %1 \n"
00045 " cmpw r0, %2 \n"
00046 " bne- 1f \n"
00047 " sync \n"
00048 " stwcx. %3, 0, %1 \n"
00049
00050 " bne- 1f \n"
00051 " li %0, 1 \n"
00052 " b 2f \n"
00053 "1: \n"
00054 " li %0, 0 \n"
00055 "2: \n"
00056 : "=r" (result)
00057 : "r" (addr), "r" (value), "r" (newvalue)
00058 : "r0"
00059 );
00060 return result;
00061 }
00062
00063 #endif
00064
00065 #if defined(__i386__) || defined(__x86_64__)
00066
00067 #ifdef __SMP__
00068 # define LOCK "lock ; "
00069 #else
00070 # define LOCK ""
00071 #endif
00072
00073 static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr)
00074 {
00075 register char ret;
00076 __asm__ __volatile__ (
00077 "# CAS \n\t"
00078 LOCK "cmpxchg %2, (%1) \n\t"
00079 "sete %0 \n\t"
00080 : "=a" (ret)
00081 : "c" (addr), "d" (newvalue), "a" (value)
00082 );
00083 return ret;
00084 }
00085
00086 #endif
00087
00088 #endif
00089
00090 #ifdef __linux__
00091
00092 #ifdef __PPC__
00093
00094 static inline int CAS(register UInt32 value, register UInt32 newvalue, register volatile void* addr)
00095 {
00096 register int result;
00097 register UInt32 tmp;
00098 asm volatile (
00099 "# CAS \n"
00100 " lwarx %4, 0, %1 \n"
00101 " cmpw %4, %2 \n"
00102 " bne- 1f \n"
00103 " sync \n"
00104 " stwcx. %3, 0, %1 \n"
00105
00106 " bne- 1f \n"
00107 " li %0, 1 \n"
00108 " b 2f \n"
00109 "1: \n"
00110 " li %0, 0 \n"
00111 "2: \n"
00112 : "=r" (result)
00113 : "r" (addr), "r" (value), "r" (newvalue), "r" (tmp)
00114 );
00115 return result;
00116 }
00117
00118 #endif
00119
00120 #if defined(__i386__) || defined(__x86_64__)
00121
00122 #ifdef __SMP__
00123 # define LOCK "lock ; "
00124 #else
00125 # define LOCK ""
00126 #endif
00127
00128 static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr)
00129 {
00130 register char ret;
00131 __asm__ __volatile__ (
00132 "# CAS \n\t"
00133 LOCK "cmpxchg %2, (%1) \n\t"
00134 "sete %0 \n\t"
00135 : "=a" (ret)
00136 : "c" (addr), "d" (newvalue), "a" (value)
00137 );
00138 return ret;
00139 }
00140
00141 #endif
00142
00143 #endif
00144
00145 #ifdef WIN32
00146
00147 #ifdef __SMP__
00148 # define LOCK lock
00149 #else
00150 # define LOCK
00151 #endif
00152
00153 #define inline __inline
00154
00155
00156
00157
00158 inline char CAS (volatile UInt32 value, UInt32 newvalue, volatile void * addr)
00159 {
00160 register char c;
00161 __asm {
00162 push ebx
00163 push esi
00164 mov esi, addr
00165 mov eax, value
00166 mov ebx, newvalue
00167 LOCK cmpxchg dword ptr [esi], ebx
00168 sete c
00169 pop esi
00170 pop ebx
00171 }
00172 return c;
00173 }
00174
00175 #endif
00176
00177 static inline long INC_ATOMIC(volatile SInt32* val)
00178 {
00179 SInt32 actual;
00180 do {
00181 actual = *val;
00182 } while (!CAS(actual, actual + 1, val));
00183 return actual;
00184 }
00185
00186 static inline long DEC_ATOMIC(volatile SInt32* val)
00187 {
00188 SInt32 actual;
00189 do {
00190 actual = *val;
00191 } while (!CAS(actual, actual - 1, val));
00192 return actual;
00193 }
00194
00195 #endif
00196
00197