00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef QATOMIC_I386_H
00043 #define QATOMIC_I386_H
00044
00045 QT_BEGIN_HEADER
00046 QT_BEGIN_NAMESPACE
00047
00048 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
00049 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
00050
00051 inline bool QBasicAtomicInt::isReferenceCountingNative()
00052 { return true; }
00053 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
00054 { return true; }
00055
00056 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
00057 #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
00058
00059 inline bool QBasicAtomicInt::isTestAndSetNative()
00060 { return true; }
00061 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
00062 { return true; }
00063
00064 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00065 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
00066
00067 inline bool QBasicAtomicInt::isFetchAndStoreNative()
00068 { return true; }
00069 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
00070 { return true; }
00071
00072 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00073 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
00074
00075 inline bool QBasicAtomicInt::isFetchAndAddNative()
00076 { return true; }
00077 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
00078 { return true; }
00079
00080 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
00081 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
00082
00083 template <typename T>
00084 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
00085 { return true; }
00086 template <typename T>
00087 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
00088 { return true; }
00089
00090 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00091 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
00092
00093 template <typename T>
00094 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
00095 { return true; }
00096 template <typename T>
00097 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
00098 { return true; }
00099
00100 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00101 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
00102
00103 template <typename T>
00104 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
00105 { return true; }
00106 template <typename T>
00107 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
00108 { return true; }
00109
00110 #if defined(Q_CC_GNU) || defined(Q_CC_INTEL)
00111
00112 inline bool QBasicAtomicInt::ref()
00113 {
00114 unsigned char ret;
00115 asm volatile("lock\n"
00116 "incl %0\n"
00117 "setne %1"
00118 : "=m" (_q_value), "=qm" (ret)
00119 : "m" (_q_value)
00120 : "memory");
00121 return ret != 0;
00122 }
00123
00124 inline bool QBasicAtomicInt::deref()
00125 {
00126 unsigned char ret;
00127 asm volatile("lock\n"
00128 "decl %0\n"
00129 "setne %1"
00130 : "=m" (_q_value), "=qm" (ret)
00131 : "m" (_q_value)
00132 : "memory");
00133 return ret != 0;
00134 }
00135
00136 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00137 {
00138 unsigned char ret;
00139 asm volatile("lock\n"
00140 "cmpxchgl %3,%2\n"
00141 "sete %1\n"
00142 : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
00143 : "r" (newValue), "0" (expectedValue)
00144 : "memory");
00145 return ret != 0;
00146 }
00147
00148 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00149 {
00150 asm volatile("xchgl %0,%1"
00151 : "=r" (newValue), "+m" (_q_value)
00152 : "0" (newValue)
00153 : "memory");
00154 return newValue;
00155 }
00156
00157 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00158 {
00159 asm volatile("lock\n"
00160 "xaddl %0,%1"
00161 : "=r" (valueToAdd), "+m" (_q_value)
00162 : "0" (valueToAdd)
00163 : "memory");
00164 return valueToAdd;
00165 }
00166
00167 template <typename T>
00168 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00169 {
00170 unsigned char ret;
00171 asm volatile("lock\n"
00172 "cmpxchgl %3,%2\n"
00173 "sete %1\n"
00174 : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
00175 : "r" (newValue), "0" (expectedValue)
00176 : "memory");
00177 return ret != 0;
00178 }
00179
00180 template <typename T>
00181 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00182 {
00183 asm volatile("xchgl %0,%1"
00184 : "=r" (newValue), "+m" (_q_value)
00185 : "0" (newValue)
00186 : "memory");
00187 return newValue;
00188 }
00189
00190 template <typename T>
00191 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
00192 {
00193 asm volatile("lock\n"
00194 "xaddl %0,%1"
00195 : "=r" (valueToAdd), "+m" (_q_value)
00196 : "0" (valueToAdd * sizeof(T))
00197 : "memory");
00198 return reinterpret_cast<T *>(valueToAdd);
00199 }
00200
00201 #else
00202
00203 extern "C" {
00204 Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
00205 Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
00206 Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
00207 Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
00208 Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
00209 Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
00210 Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
00211 Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, int value);
00212 }
00213
00214 inline bool QBasicAtomicInt::ref()
00215 {
00216 return q_atomic_increment(&_q_value) != 0;
00217 }
00218
00219 inline bool QBasicAtomicInt::deref()
00220 {
00221 return q_atomic_decrement(&_q_value) != 0;
00222 }
00223
00224 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00225 {
00226 return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
00227 }
00228
00229 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00230 {
00231 return q_atomic_set_int(&_q_value, newValue);
00232 }
00233
00234 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00235 {
00236 return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
00237 }
00238
00239 template <typename T>
00240 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00241 {
00242 return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue);
00243 }
00244
00245 template <typename T>
00246 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00247 {
00248 return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
00249 }
00250
00251 template <typename T>
00252 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
00253 {
00254 return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
00255 }
00256
00257 #endif
00258
00259 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
00260 {
00261 return testAndSetOrdered(expectedValue, newValue);
00262 }
00263
00264 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
00265 {
00266 return testAndSetOrdered(expectedValue, newValue);
00267 }
00268
00269 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
00270 {
00271 return testAndSetOrdered(expectedValue, newValue);
00272 }
00273
00274 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
00275 {
00276 return fetchAndStoreOrdered(newValue);
00277 }
00278
00279 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
00280 {
00281 return fetchAndStoreOrdered(newValue);
00282 }
00283
00284 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
00285 {
00286 return fetchAndStoreOrdered(newValue);
00287 }
00288
00289 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
00290 {
00291 return fetchAndAddOrdered(valueToAdd);
00292 }
00293
00294 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
00295 {
00296 return fetchAndAddOrdered(valueToAdd);
00297 }
00298
00299 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
00300 {
00301 return fetchAndAddOrdered(valueToAdd);
00302 }
00303
00304 template <typename T>
00305 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
00306 {
00307 return testAndSetOrdered(expectedValue, newValue);
00308 }
00309
00310 template <typename T>
00311 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
00312 {
00313 return testAndSetOrdered(expectedValue, newValue);
00314 }
00315
00316 template <typename T>
00317 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
00318 {
00319 return testAndSetOrdered(expectedValue, newValue);
00320 }
00321
00322 template <typename T>
00323 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
00324 {
00325 return fetchAndStoreOrdered(newValue);
00326 }
00327
00328 template <typename T>
00329 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
00330 {
00331 return fetchAndStoreOrdered(newValue);
00332 }
00333
00334 template <typename T>
00335 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
00336 {
00337 return fetchAndStoreOrdered(newValue);
00338 }
00339
00340 template <typename T>
00341 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
00342 {
00343 return fetchAndAddOrdered(valueToAdd);
00344 }
00345
00346 template <typename T>
00347 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
00348 {
00349 return fetchAndAddOrdered(valueToAdd);
00350 }
00351
00352 template <typename T>
00353 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
00354 {
00355 return fetchAndAddOrdered(valueToAdd);
00356 }
00357
00358 QT_END_NAMESPACE
00359 QT_END_HEADER
00360
00361 #endif // QATOMIC_I386_H