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_ARMV6_H
00043 #define QATOMIC_ARMV6_H
00044
00045 QT_BEGIN_HEADER
00046
00047 QT_BEGIN_NAMESPACE
00048 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
00049
00050 inline bool QBasicAtomicInt::isReferenceCountingNative()
00051 { return true; }
00052 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
00053 { return false; }
00054
00055 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
00056
00057 inline bool QBasicAtomicInt::isTestAndSetNative()
00058 { return true; }
00059 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
00060 { return false; }
00061
00062 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00063
00064 inline bool QBasicAtomicInt::isFetchAndStoreNative()
00065 { return true; }
00066 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
00067 { return false; }
00068
00069 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00070
00071 inline bool QBasicAtomicInt::isFetchAndAddNative()
00072 { return true; }
00073 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
00074 { return false; }
00075
00076 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
00077
00078 template <typename T>
00079 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
00080 { return true; }
00081 template <typename T>
00082 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
00083 { return false; }
00084
00085 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00086
00087 template <typename T>
00088 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
00089 { return true; }
00090 template <typename T>
00091 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
00092 { return false; }
00093
00094 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00095
00096 template <typename T>
00097 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
00098 { return true; }
00099 template <typename T>
00100 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
00101 { return false; }
00102
00103 #ifndef Q_CC_RVCT
00104
00105 inline bool QBasicAtomicInt::ref()
00106 {
00107 register int newValue;
00108 register int result;
00109 asm volatile("0:\n"
00110 "ldrex %[newValue], [%[_q_value]]\n"
00111 "add %[newValue], %[newValue], #1\n"
00112 "strex %[result], %[newValue], [%[_q_value]]\n"
00113 "teq %[result], #0\n"
00114 "bne 0b\n"
00115 : [newValue] "=&r" (newValue),
00116 [result] "=&r" (result),
00117 "+m" (_q_value)
00118 : [_q_value] "r" (&_q_value)
00119 : "cc", "memory");
00120 return newValue != 0;
00121 }
00122
00123 inline bool QBasicAtomicInt::deref()
00124 {
00125 register int newValue;
00126 register int result;
00127 asm volatile("0:\n"
00128 "ldrex %[newValue], [%[_q_value]]\n"
00129 "sub %[newValue], %[newValue], #1\n"
00130 "strex %[result], %[newValue], [%[_q_value]]\n"
00131 "teq %[result], #0\n"
00132 "bne 0b\n"
00133 : [newValue] "=&r" (newValue),
00134 [result] "=&r" (result),
00135 "+m" (_q_value)
00136 : [_q_value] "r" (&_q_value)
00137 : "cc", "memory");
00138 return newValue != 0;
00139 }
00140
00141 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00142 {
00143 register int result;
00144 asm volatile("0:\n"
00145 "ldrex %[result], [%[_q_value]]\n"
00146 "eors %[result], %[result], %[expectedValue]\n"
00147 "strexeq %[result], %[newValue], [%[_q_value]]\n"
00148 "teqeq %[result], #1\n"
00149 "beq 0b\n"
00150 : [result] "=&r" (result),
00151 "+m" (_q_value)
00152 : [expectedValue] "r" (expectedValue),
00153 [newValue] "r" (newValue),
00154 [_q_value] "r" (&_q_value)
00155 : "cc", "memory");
00156 return result == 0;
00157 }
00158
00159 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00160 {
00161 register int originalValue;
00162 register int result;
00163 asm volatile("0:\n"
00164 "ldrex %[originalValue], [%[_q_value]]\n"
00165 "strex %[result], %[newValue], [%[_q_value]]\n"
00166 "teq %[result], #0\n"
00167 "bne 0b\n"
00168 : [originalValue] "=&r" (originalValue),
00169 [result] "=&r" (result),
00170 "+m" (_q_value)
00171 : [newValue] "r" (newValue),
00172 [_q_value] "r" (&_q_value)
00173 : "cc", "memory");
00174 return originalValue;
00175 }
00176
00177 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00178 {
00179 register int originalValue;
00180 register int newValue;
00181 register int result;
00182 asm volatile("0:\n"
00183 "ldrex %[originalValue], [%[_q_value]]\n"
00184 "add %[newValue], %[originalValue], %[valueToAdd]\n"
00185 "strex %[result], %[newValue], [%[_q_value]]\n"
00186 "teq %[result], #0\n"
00187 "bne 0b\n"
00188 : [originalValue] "=&r" (originalValue),
00189 [newValue] "=&r" (newValue),
00190 [result] "=&r" (result),
00191 "+m" (_q_value)
00192 : [valueToAdd] "r" (valueToAdd),
00193 [_q_value] "r" (&_q_value)
00194 : "cc", "memory");
00195 return originalValue;
00196 }
00197
00198 template <typename T>
00199 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00200 {
00201 register T *result;
00202 asm volatile("0:\n"
00203 "ldrex %[result], [%[_q_value]]\n"
00204 "eors %[result], %[result], %[expectedValue]\n"
00205 "strexeq %[result], %[newValue], [%[_q_value]]\n"
00206 "teqeq %[result], #1\n"
00207 "beq 0b\n"
00208 : [result] "=&r" (result),
00209 "+m" (_q_value)
00210 : [expectedValue] "r" (expectedValue),
00211 [newValue] "r" (newValue),
00212 [_q_value] "r" (&_q_value)
00213 : "cc", "memory");
00214 return result == 0;
00215 }
00216
00217 template <typename T>
00218 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00219 {
00220 register T *originalValue;
00221 register int result;
00222 asm volatile("0:\n"
00223 "ldrex %[originalValue], [%[_q_value]]\n"
00224 "strex %[result], %[newValue], [%[_q_value]]\n"
00225 "teq %[result], #0\n"
00226 "bne 0b\n"
00227 : [originalValue] "=&r" (originalValue),
00228 [result] "=&r" (result),
00229 "+m" (_q_value)
00230 : [newValue] "r" (newValue),
00231 [_q_value] "r" (&_q_value)
00232 : "cc", "memory");
00233 return originalValue;
00234 }
00235
00236 template <typename T>
00237 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
00238 {
00239 register T *originalValue;
00240 register T *newValue;
00241 register int result;
00242 asm volatile("0:\n"
00243 "ldrex %[originalValue], [%[_q_value]]\n"
00244 "add %[newValue], %[originalValue], %[valueToAdd]\n"
00245 "strex %[result], %[newValue], [%[_q_value]]\n"
00246 "teq %[result], #0\n"
00247 "bne 0b\n"
00248 : [originalValue] "=&r" (originalValue),
00249 [newValue] "=&r" (newValue),
00250 [result] "=&r" (result),
00251 "+m" (_q_value)
00252 : [valueToAdd] "r" (valueToAdd * sizeof(T)),
00253 [_q_value] "r" (&_q_value)
00254 : "cc", "memory");
00255 return originalValue;
00256 }
00257
00258 #else
00259
00260
00261
00262
00263
00264
00265
00266
00267 #pragma push
00268 #pragma arm
00269
00270 inline bool QBasicAtomicInt::ref()
00271 {
00272 register int newValue;
00273 register int result;
00274 retry:
00275 __asm {
00276 ldrex newValue, [&_q_value]
00277 add newValue, newValue, #1
00278 strex result, newValue, [&_q_value]
00279 teq result, #0
00280 bne retry
00281 }
00282 return newValue != 0;
00283 }
00284
00285 inline bool QBasicAtomicInt::deref()
00286 {
00287 register int newValue;
00288 register int result;
00289 retry:
00290 __asm {
00291 ldrex newValue, [&_q_value]
00292 sub newValue, newValue, #1
00293 strex result, newValue, [&_q_value]
00294 teq result, #0
00295 bne retry
00296 }
00297 return newValue != 0;
00298 }
00299
00300 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00301 {
00302 register int result;
00303 retry:
00304 __asm {
00305 ldrex result, [&_q_value]
00306 eors result, result, expectedValue
00307 strexeq result, newValue, [&_q_value]
00308 teqeq result, #1
00309 beq retry
00310 }
00311 return result == 0;
00312 }
00313
00314 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00315 {
00316 register int originalValue;
00317 register int result;
00318 retry:
00319 __asm {
00320 ldrex originalValue, [&_q_value]
00321 strex result, newValue, [&_q_value]
00322 teq result, #0
00323 bne retry
00324 }
00325 return originalValue;
00326 }
00327
00328 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00329 {
00330 register int originalValue;
00331 register int newValue;
00332 register int result;
00333 retry:
00334 __asm {
00335 ldrex originalValue, [&_q_value]
00336 add newValue, originalValue, valueToAdd
00337 strex result, newValue, [&_q_value]
00338 teq result, #0
00339 bne retry
00340 }
00341 return originalValue;
00342 }
00343
00344 template <typename T>
00345 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00346 {
00347 register T *result;
00348 retry:
00349 __asm {
00350 ldrex result, [&_q_value]
00351 eors result, result, expectedValue
00352 strexeq result, newValue, [&_q_value]
00353 teqeq result, #1
00354 beq retry
00355 }
00356 return result == 0;
00357 }
00358
00359 template <typename T>
00360 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00361 {
00362 register T *originalValue;
00363 register int result;
00364 retry:
00365 __asm {
00366 ldrex originalValue, [&_q_value]
00367 strex result, newValue, [&_q_value]
00368 teq result, #0
00369 bne retry
00370 }
00371 return originalValue;
00372 }
00373
00374 template <typename T>
00375 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
00376 {
00377 register T *originalValue;
00378 register T *newValue;
00379 register int result;
00380 retry:
00381 __asm {
00382 ldrex originalValue, [&_q_value]
00383 add newValue, originalValue, valueToAdd * sizeof(T)
00384 strex result, newValue, [&_q_value]
00385 teq result, #0
00386 bne retry
00387 }
00388 return originalValue;
00389 }
00390
00391
00392 #pragma pop
00393 #endif
00394
00395
00396
00397 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
00398 {
00399 return testAndSetOrdered(expectedValue, newValue);
00400 }
00401
00402 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
00403 {
00404 return testAndSetOrdered(expectedValue, newValue);
00405 }
00406
00407 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
00408 {
00409 return testAndSetOrdered(expectedValue, newValue);
00410 }
00411
00412 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
00413 {
00414 return fetchAndStoreOrdered(newValue);
00415 }
00416
00417 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
00418 {
00419 return fetchAndStoreOrdered(newValue);
00420 }
00421
00422 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
00423 {
00424 return fetchAndStoreOrdered(newValue);
00425 }
00426
00427 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
00428 {
00429 return fetchAndAddOrdered(valueToAdd);
00430 }
00431
00432 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
00433 {
00434 return fetchAndAddOrdered(valueToAdd);
00435 }
00436
00437 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
00438 {
00439 return fetchAndAddOrdered(valueToAdd);
00440 }
00441
00442 template <typename T>
00443 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
00444 {
00445 return testAndSetOrdered(expectedValue, newValue);
00446 }
00447
00448 template <typename T>
00449 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
00450 {
00451 return testAndSetOrdered(expectedValue, newValue);
00452 }
00453
00454 template <typename T>
00455 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
00456 {
00457 return testAndSetOrdered(expectedValue, newValue);
00458 }
00459
00460 template <typename T>
00461 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
00462 {
00463 return fetchAndStoreOrdered(newValue);
00464 }
00465
00466 template <typename T>
00467 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
00468 {
00469 return fetchAndStoreOrdered(newValue);
00470 }
00471
00472 template <typename T>
00473 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
00474 {
00475 return fetchAndStoreOrdered(newValue);
00476 }
00477
00478 template <typename T>
00479 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
00480 {
00481 return fetchAndAddOrdered(valueToAdd);
00482 }
00483
00484 template <typename T>
00485 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
00486 {
00487 return fetchAndAddOrdered(valueToAdd);
00488 }
00489
00490 template <typename T>
00491 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
00492 {
00493 return fetchAndAddOrdered(valueToAdd);
00494 }
00495
00496 QT_END_NAMESPACE
00497
00498 QT_END_HEADER
00499
00500 #endif // QATOMIC_ARMV6_H