Go to the
documentation of this file.
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_SH_H
00043 #define QATOMIC_SH_H
00044
00045 QT_BEGIN_HEADER
00046
00047 QT_BEGIN_NAMESPACE
00048
00049 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
00050
00051 inline bool QBasicAtomicInt::isReferenceCountingNative()
00052 { return false; }
00053 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
00054 { return false; }
00055
00056 #define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
00057
00058 inline bool QBasicAtomicInt::isTestAndSetNative()
00059 { return false; }
00060 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
00061 { return false; }
00062
00063 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
00064
00065 inline bool QBasicAtomicInt::isFetchAndStoreNative()
00066 { return false; }
00067 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
00068 { return false; }
00069
00070 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
00071
00072 inline bool QBasicAtomicInt::isFetchAndAddNative()
00073 { return false; }
00074 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
00075 { return false; }
00076
00077 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
00078
00079 template <typename T>
00080 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
00081 { return false; }
00082 template <typename T>
00083 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
00084 { return false; }
00085
00086 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
00087
00088 template <typename T>
00089 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
00090 { return false; }
00091 template <typename T>
00092 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
00093 { return false; }
00094
00095 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
00096
00097 template <typename T>
00098 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
00099 { return false; }
00100 template <typename T>
00101 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
00102 { return false; }
00103
00104 extern Q_CORE_EXPORT volatile char qt_atomic_lock;
00105 Q_CORE_EXPORT void qt_atomic_yield(int *count);
00106
00107 inline int qt_atomic_tasb(volatile char *ptr)
00108 {
00109 register int ret;
00110 asm volatile("tas.b @%2\n"
00111 "movt %0"
00112 : "=&r"(ret), "=m"(*ptr)
00113 : "r"(ptr)
00114 : "cc", "memory");
00115 return ret;
00116 }
00117
00118
00119
00120 inline bool QBasicAtomicInt::ref()
00121 {
00122 int count = 0;
00123 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00124 qt_atomic_yield(&count);
00125 int originalValue = _q_value++;
00126 qt_atomic_lock = 0;
00127 return originalValue != -1;
00128 }
00129
00130 inline bool QBasicAtomicInt::deref()
00131 {
00132 int count = 0;
00133 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00134 qt_atomic_yield(&count);
00135 int originalValue = _q_value--;
00136 qt_atomic_lock = 0;
00137 return originalValue != 1;
00138 }
00139
00140
00141
00142 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00143 {
00144 bool returnValue = false;
00145 int count = 0;
00146 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00147 qt_atomic_yield(&count);
00148 if (_q_value == expectedValue) {
00149 _q_value = newValue;
00150 returnValue = true;
00151 }
00152 qt_atomic_lock = 0;
00153 return returnValue;
00154 }
00155
00156 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
00157 {
00158 return testAndSetOrdered(expectedValue, newValue);
00159 }
00160
00161 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
00162 {
00163 return testAndSetOrdered(expectedValue, newValue);
00164 }
00165
00166 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
00167 {
00168 return testAndSetOrdered(expectedValue, newValue);
00169 }
00170
00171
00172
00173 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00174 {
00175 int count = 0;
00176 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00177 qt_atomic_yield(&count);
00178 int originalValue = _q_value;
00179 _q_value = newValue;
00180 qt_atomic_lock = 0;
00181 return originalValue;
00182 }
00183
00184 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
00185 {
00186 return fetchAndStoreOrdered(newValue);
00187 }
00188
00189 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
00190 {
00191 return fetchAndStoreOrdered(newValue);
00192 }
00193
00194 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
00195 {
00196 return fetchAndStoreOrdered(newValue);
00197 }
00198
00199
00200
00201 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00202 {
00203 int count = 0;
00204 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00205 qt_atomic_yield(&count);
00206 int originalValue = _q_value;
00207 _q_value += valueToAdd;
00208 qt_atomic_lock = 0;
00209 return originalValue;
00210 }
00211
00212 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
00213 {
00214 return fetchAndAddOrdered(valueToAdd);
00215 }
00216
00217 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
00218 {
00219 return fetchAndAddOrdered(valueToAdd);
00220 }
00221
00222 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
00223 {
00224 return fetchAndAddOrdered(valueToAdd);
00225 }
00226
00227
00228
00229 template <typename T>
00230 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00231 {
00232 bool returnValue = false;
00233 int count = 0;
00234 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00235 qt_atomic_yield(&count);
00236 if (_q_value == expectedValue) {
00237 _q_value = newValue;
00238 returnValue = true;
00239 }
00240 qt_atomic_lock = 0;
00241 return returnValue;
00242 }
00243
00244 template <typename T>
00245 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
00246 {
00247 return testAndSetOrdered(expectedValue, newValue);
00248 }
00249
00250 template <typename T>
00251 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
00252 {
00253 return testAndSetOrdered(expectedValue, newValue);
00254 }
00255
00256 template <typename T>
00257 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
00258 {
00259 return testAndSetOrdered(expectedValue, newValue);
00260 }
00261
00262
00263
00264 template <typename T>
00265 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00266 {
00267 int count = 0;
00268 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00269 qt_atomic_yield(&count);
00270 T *originalValue = _q_value;
00271 _q_value = newValue;
00272 qt_atomic_lock = 0;
00273 return originalValue;
00274 }
00275
00276 template <typename T>
00277 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
00278 {
00279 return fetchAndStoreOrdered(newValue);
00280 }
00281
00282 template <typename T>
00283 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
00284 {
00285 return fetchAndStoreOrdered(newValue);
00286 }
00287
00288 template <typename T>
00289 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
00290 {
00291 return fetchAndStoreOrdered(newValue);
00292 }
00293
00294
00295
00296 template <typename T>
00297 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
00298 {
00299 int count = 0;
00300 while (qt_atomic_tasb(&qt_atomic_lock) == 0)
00301 qt_atomic_yield(&count);
00302 T *originalValue = (_q_value);
00303 _q_value += valueToAdd;
00304 qt_atomic_lock = 0;
00305 return originalValue;
00306 }
00307
00308 template <typename T>
00309 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
00310 {
00311 return fetchAndAddOrdered(valueToAdd);
00312 }
00313
00314 template <typename T>
00315 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
00316 {
00317 return fetchAndAddOrdered(valueToAdd);
00318 }
00319
00320 template <typename T>
00321 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
00322 {
00323 return fetchAndAddOrdered(valueToAdd);
00324 }
00325
00326 QT_END_NAMESPACE
00327
00328 QT_END_HEADER
00329
00330 #endif // QATOMIC_SH_H