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