00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 INLINE void AtomicAdjustI386Impl::
00022 inc(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
00023 assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
00024 #ifdef _M_IX86
00025
00026 TVOLATILE Integer *var_ptr = &var;
00027 __asm {
00028 mov edx, var_ptr;
00029 lock inc dword ptr [edx];
00030 }
00031 #elif !defined(__EDG__)
00032
00033 __asm__ __volatile__("lock; incl %0"
00034 :"=m" (var)
00035 :"m" (&var));
00036 #endif // __EDG__
00037 }
00038
00039
00040
00041
00042
00043
00044
00045
00046 INLINE bool AtomicAdjustI386Impl::
00047 dec(TVOLATILE AtomicAdjustI386Impl::Integer &var) {
00048 assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
00049 unsigned char c;
00050 #ifdef _M_IX86
00051
00052 TVOLATILE Integer *var_ptr = &var;
00053 __asm {
00054 mov edx, var_ptr;
00055 lock dec dword ptr [edx];
00056 sete c;
00057 }
00058 #elif !defined(__EDG__)
00059
00060 __asm__ __volatile__("lock; decl %0; sete %1"
00061 :"=m" (var), "=qm" (c)
00062 :"m" (&var) : "memory");
00063 #endif // __EDG__
00064 return (c == 0);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073 INLINE void AtomicAdjustI386Impl::
00074 add(TVOLATILE AtomicAdjustI386Impl::Integer &var, AtomicAdjustI386Impl::Integer delta) {
00075 assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
00076 Integer orig_value = var;
00077 while (compare_and_exchange(var, orig_value, orig_value + delta) != orig_value) {
00078 orig_value = var;
00079 }
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
00089 set(TVOLATILE AtomicAdjustI386Impl::Integer &var,
00090 AtomicAdjustI386Impl::Integer new_value) {
00091 assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
00092 Integer orig_value = var;
00093 var = new_value;
00094 return orig_value;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
00107 get(const TVOLATILE AtomicAdjustI386Impl::Integer &var) {
00108 assert((((size_t)&var) & (sizeof(Integer) - 1)) == 0);
00109 return var;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 INLINE AtomicAdjustI386Impl::Pointer AtomicAdjustI386Impl::
00119 set_ptr(TVOLATILE AtomicAdjustI386Impl::Pointer &var,
00120 AtomicAdjustI386Impl::Pointer new_value) {
00121 assert((((size_t)&var) & (sizeof(Pointer) - 1)) == 0);
00122 Pointer orig_value = var;
00123 var = new_value;
00124 return orig_value;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 INLINE AtomicAdjustI386Impl::Pointer AtomicAdjustI386Impl::
00137 get_ptr(const TVOLATILE AtomicAdjustI386Impl::Pointer &var) {
00138 assert((((size_t)&var) & (sizeof(Pointer) - 1)) == 0);
00139 return var;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 INLINE AtomicAdjustI386Impl::Integer AtomicAdjustI386Impl::
00162 compare_and_exchange(TVOLATILE AtomicAdjustI386Impl::Integer &mem,
00163 AtomicAdjustI386Impl::Integer old_value,
00164 AtomicAdjustI386Impl::Integer new_value) {
00165 assert((((size_t)&mem) & (sizeof(Integer) - 1)) == 0);
00166 Integer prev;
00167 #ifdef _M_IX86
00168
00169 TVOLATILE Integer *mem_ptr = &mem;
00170 __asm {
00171 mov edx, mem_ptr;
00172 mov ecx, new_value;
00173 mov eax, old_value;
00174 lock cmpxchg dword ptr [edx], ecx;
00175 mov prev, eax;
00176 }
00177 #elif !defined(__EDG__)
00178
00179 __asm__ __volatile__("lock; cmpxchgl %1,%2"
00180 : "=a"(prev)
00181 : "r"(new_value), "m"(mem), "0"(old_value)
00182 : "memory");
00183 #endif // __EDG__
00184 return prev;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194 INLINE AtomicAdjustI386Impl::Pointer AtomicAdjustI386Impl::
00195 compare_and_exchange_ptr(TVOLATILE AtomicAdjustI386Impl::Pointer &mem,
00196 AtomicAdjustI386Impl::Pointer old_value,
00197 AtomicAdjustI386Impl::Pointer new_value) {
00198 assert((((size_t)&mem) & (sizeof(Pointer) - 1)) == 0);
00199 Pointer prev;
00200 #ifdef _M_IX86
00201
00202 TVOLATILE Pointer *mem_ptr = &mem;
00203 __asm {
00204 mov edx, mem_ptr;
00205 mov ecx, new_value;
00206 mov eax, old_value;
00207 lock cmpxchg dword ptr [edx], ecx;
00208 mov prev, eax;
00209 }
00210 #elif !defined(__EDG__)
00211
00212 __asm__ __volatile__("lock; cmpxchgl %1,%2"
00213 : "=a"(prev)
00214 : "r"(new_value), "m"(mem), "0"(old_value)
00215 : "memory");
00216 #endif // __EDG__
00217 return prev;
00218 }