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_ALPHA_H
00043 #define QATOMIC_ALPHA_H
00044
00045 QT_BEGIN_HEADER
00046
00047 QT_BEGIN_NAMESPACE
00048
00049 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
00050
00051 inline bool QBasicAtomicInt::isReferenceCountingNative()
00052 { return true; }
00053 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
00054 { return false; }
00055
00056 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
00057
00058 inline bool QBasicAtomicInt::isTestAndSetNative()
00059 { return true; }
00060 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
00061 { return false; }
00062
00063 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00064
00065 inline bool QBasicAtomicInt::isFetchAndStoreNative()
00066 { return true; }
00067 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
00068 { return false; }
00069
00070 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00071
00072 inline bool QBasicAtomicInt::isFetchAndAddNative()
00073 { return true; }
00074 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
00075 { return false; }
00076
00077 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
00078
00079 template <typename T>
00080 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
00081 { return true; }
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_ALWAYS_NATIVE
00087
00088 template <typename T>
00089 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
00090 { return true; }
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_ALWAYS_NATIVE
00096
00097 template <typename T>
00098 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
00099 { return true; }
00100 template <typename T>
00101 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
00102 { return false; }
00103
00104 #if defined(Q_CC_GNU)
00105
00106 inline bool QBasicAtomicInt::ref()
00107 {
00108 register int old, tmp;
00109 asm volatile("1:\n"
00110 "ldl_l %0,%2\n"
00111 "addl %0,1,%1\n"
00112 "stl_c %1,%2\n"
00113 "beq %1,2f\n"
00114 "br 3f\n"
00115 "2: br 1b\n"
00116 "3:\n"
00117 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00118 :
00119 : "memory");
00120 return old != -1;
00121 }
00122
00123 inline bool QBasicAtomicInt::deref()
00124 {
00125 register int old, tmp;
00126 asm volatile("1:\n"
00127 "ldl_l %0,%2\n"
00128 "subl %0,1,%1\n"
00129 "stl_c %1,%2\n"
00130 "beq %1,2f\n"
00131 "br 3f\n"
00132 "2: br 1b\n"
00133 "3:\n"
00134 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00135 :
00136 : "memory");
00137 return old != 1;
00138 }
00139
00140 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
00141 {
00142 register int ret;
00143 asm volatile("1:\n"
00144 "ldl_l %0,%1\n"
00145 "cmpeq %0,%2,%0\n"
00146 "beq %0,3f\n"
00147 "mov %3,%0\n"
00148 "stl_c %0,%1\n"
00149 "beq %0,2f\n"
00150 "br 3f\n"
00151 "2: br 1b\n"
00152 "3:\n"
00153 : "=&r" (ret), "+m" (_q_value)
00154 : "r" (expectedValue), "r" (newValue)
00155 : "memory");
00156 return ret != 0;
00157 }
00158
00159 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
00160 {
00161 register int ret;
00162 asm volatile("1:\n"
00163 "ldl_l %0,%1\n"
00164 "cmpeq %0,%2,%0\n"
00165 "beq %0,3f\n"
00166 "mov %3,%0\n"
00167 "stl_c %0,%1\n"
00168 "beq %0,2f\n"
00169 "br 3f\n"
00170 "2: br 1b\n"
00171 "3:\n"
00172 "mb\n"
00173 : "=&r" (ret), "+m" (_q_value)
00174 : "r" (expectedValue), "r" (newValue)
00175 : "memory");
00176 return ret != 0;
00177 }
00178
00179 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
00180 {
00181 register int ret;
00182 asm volatile("mb\n"
00183 "1:\n"
00184 "ldl_l %0,%1\n"
00185 "cmpeq %0,%2,%0\n"
00186 "beq %0,3f\n"
00187 "mov %3,%0\n"
00188 "stl_c %0,%1\n"
00189 "beq %0,2f\n"
00190 "br 3f\n"
00191 "2: br 1b\n"
00192 "3:\n"
00193 : "=&r" (ret), "+m" (_q_value)
00194 : "r" (expectedValue), "r" (newValue)
00195 : "memory");
00196 return ret != 0;
00197 }
00198
00199 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
00200 {
00201 register int old, tmp;
00202 asm volatile("1:\n"
00203 "ldl_l %0,%2\n"
00204 "mov %3,%1\n"
00205 "stl_c %1,%2\n"
00206 "beq %1,2f\n"
00207 "br 3f\n"
00208 "2: br 1b\n"
00209 "3:\n"
00210 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
00211 : "r" (newValue)
00212 : "memory");
00213 return old;
00214 }
00215
00216 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
00217 {
00218 register int old, tmp;
00219 asm volatile("1:\n"
00220 "ldl_l %0,%2\n"
00221 "mov %3,%1\n"
00222 "stl_c %1,%2\n"
00223 "beq %1,2f\n"
00224 "br 3f\n"
00225 "2: br 1b\n"
00226 "3:\n"
00227 "mb\n"
00228 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
00229 : "r" (newValue)
00230 : "memory");
00231 return old;
00232 }
00233
00234 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
00235 {
00236 register int old, tmp;
00237 asm volatile("mb\n"
00238 "1:\n"
00239 "ldl_l %0,%2\n"
00240 "mov %3,%1\n"
00241 "stl_c %1,%2\n"
00242 "beq %1,2f\n"
00243 "br 3f\n"
00244 "2: br 1b\n"
00245 "3:\n"
00246 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
00247 : "r" (newValue)
00248 : "memory");
00249 return old;
00250 }
00251
00252 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
00253 {
00254 register int old, tmp;
00255 asm volatile("1:\n"
00256 "ldl_l %0,%2\n"
00257 "addl %0,%3,%1\n"
00258 "stl_c %1,%2\n"
00259 "beq %1,2f\n"
00260 "br 3f\n"
00261 "2: br 1b\n"
00262 "3:\n"
00263 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00264 : "r" (valueToAdd)
00265 : "memory");
00266 return old;
00267 }
00268
00269 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
00270 {
00271 register int old, tmp;
00272 asm volatile("1:\n"
00273 "ldl_l %0,%2\n"
00274 "addl %0,%3,%1\n"
00275 "stl_c %1,%2\n"
00276 "beq %1,2f\n"
00277 "br 3f\n"
00278 "2: br 1b\n"
00279 "3:\n"
00280 "mb\n"
00281 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00282 : "r" (valueToAdd)
00283 : "memory");
00284 return old;
00285 }
00286
00287 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
00288 {
00289 register int old, tmp;
00290 asm volatile("mb\n"
00291 "1:\n"
00292 "ldl_l %0,%2\n"
00293 "addl %0,%3,%1\n"
00294 "stl_c %1,%2\n"
00295 "beq %1,2f\n"
00296 "br 3f\n"
00297 "2: br 1b\n"
00298 "3:\n"
00299 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00300 : "r" (valueToAdd)
00301 : "memory");
00302 return old;
00303 }
00304
00305 template <typename T>
00306 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
00307 {
00308 register void *ret;
00309 asm volatile("1:\n"
00310 "ldq_l %0,%1\n"
00311 "cmpeq %0,%2,%0\n"
00312 "beq %0,3f\n"
00313 "mov %3,%0\n"
00314 "stq_c %0,%1\n"
00315 "beq %0,2f\n"
00316 "br 3f\n"
00317 "2: br 1b\n"
00318 "3:\n"
00319 : "=&r" (ret), "+m" (_q_value)
00320 : "r" (expectedValue), "r" (newValue)
00321 : "memory");
00322 return ret != 0;
00323 }
00324
00325 template <typename T>
00326 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
00327 {
00328 register void *ret;
00329 asm volatile("1:\n"
00330 "ldq_l %0,%1\n"
00331 "cmpeq %0,%2,%0\n"
00332 "beq %0,3f\n"
00333 "mov %3,%0\n"
00334 "stq_c %0,%1\n"
00335 "beq %0,2f\n"
00336 "br 3f\n"
00337 "2: br 1b\n"
00338 "3:\n"
00339 "mb\n"
00340 : "=&r" (ret), "+m" (_q_value)
00341 : "r" (expectedValue), "r" (newValue)
00342 : "memory");
00343 return ret != 0;
00344 }
00345
00346 template <typename T>
00347 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
00348 {
00349 register void *ret;
00350 asm volatile("mb\n"
00351 "1:\n"
00352 "ldq_l %0,%1\n"
00353 "cmpeq %0,%2,%0\n"
00354 "beq %0,3f\n"
00355 "mov %3,%0\n"
00356 "stq_c %0,%1\n"
00357 "beq %0,2f\n"
00358 "br 3f\n"
00359 "2: br 1b\n"
00360 "3:\n"
00361 : "=&r" (ret), "+m" (_q_value)
00362 : "r" (expectedValue), "r" (newValue)
00363 : "memory");
00364 return ret != 0;
00365 }
00366
00367 template <typename T>
00368 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
00369 {
00370 register T *old, *tmp;
00371 asm volatile("1:\n"
00372 "ldq_l %0,%2\n"
00373 "mov %3,%1\n"
00374 "stq_c %1,%2\n"
00375 "beq %1,2f\n"
00376 "br 3f\n"
00377 "2: br 1b\n"
00378 "3:\n"
00379 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
00380 : "r" (newValue)
00381 : "memory");
00382 return old;
00383 }
00384
00385 template <typename T>
00386 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
00387 {
00388 register T *old, *tmp;
00389 asm volatile("1:\n"
00390 "ldq_l %0,%2\n"
00391 "mov %3,%1\n"
00392 "stq_c %1,%2\n"
00393 "beq %1,2f\n"
00394 "br 3f\n"
00395 "2: br 1b\n"
00396 "3:\n"
00397 "mb\n"
00398 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
00399 : "r" (newValue)
00400 : "memory");
00401 return old;
00402 }
00403
00404 template <typename T>
00405 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
00406 {
00407 register T *old, *tmp;
00408 asm volatile("mb\n"
00409 "1:\n"
00410 "ldq_l %0,%2\n"
00411 "mov %3,%1\n"
00412 "stq_c %1,%2\n"
00413 "beq %1,2f\n"
00414 "br 3f\n"
00415 "2: br 1b\n"
00416 "3:\n"
00417 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
00418 : "r" (newValue)
00419 : "memory");
00420 return old;
00421 }
00422
00423 template <typename T>
00424 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
00425 {
00426 register T *old, *tmp;
00427 asm volatile("1:\n"
00428 "ldq_l %0,%2\n"
00429 "addq %0,%3,%1\n"
00430 "stq_c %1,%2\n"
00431 "beq %1,2f\n"
00432 "br 3f\n"
00433 "2: br 1b\n"
00434 "3:\n"
00435 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00436 : "r" (valueToAdd)
00437 : "memory");
00438 return reinterpret_cast<T *>(old);
00439 }
00440
00441 template <typename T>
00442 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
00443 {
00444 register T *old, *tmp;
00445 asm volatile("1:\n"
00446 "ldq_l %0,%2\n"
00447 "addq %0,%3,%1\n"
00448 "stq_c %1,%2\n"
00449 "beq %1,2f\n"
00450 "br 3f\n"
00451 "2: br 1b\n"
00452 "3:\n"
00453 "mb\n"
00454 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00455 : "r" (valueToAdd)
00456 : "memory");
00457 return reinterpret_cast<T *>(old);
00458 }
00459
00460 template <typename T>
00461 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
00462 {
00463 register T *old, *tmp;
00464 asm volatile("mb\n"
00465 "1:\n"
00466 "ldq_l %0,%2\n"
00467 "addq %0,%3,%1\n"
00468 "stq_c %1,%2\n"
00469 "beq %1,2f\n"
00470 "br 3f\n"
00471 "2: br 1b\n"
00472 "3:\n"
00473 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
00474 : "r" (valueToAdd)
00475 : "memory");
00476 return reinterpret_cast<T *>(old);
00477 }
00478
00479 #else // !Q_CC_GNU
00480
00481 extern "C" {
00482 Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
00483 Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval);
00484 Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval);
00485 Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
00486 Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
00487 Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
00488 Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
00489 Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
00490 Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
00491 Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
00492 Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value);
00493 }
00494
00495 inline bool QBasicAtomicInt::ref()
00496 {
00497 return q_atomic_increment(&_q_value) != 0;
00498 }
00499
00500 inline bool QBasicAtomicInt::deref()
00501 {
00502 return q_atomic_decrement(&_q_value) != 0;
00503 }
00504
00505 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
00506 {
00507 return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
00508 }
00509
00510 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
00511 {
00512 return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
00513 }
00514
00515 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
00516 {
00517 return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
00518 }
00519
00520 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
00521 {
00522 return q_atomic_set_int(&_q_value, newValue);
00523 }
00524
00525 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
00526 {
00527 return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
00528 }
00529
00530 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
00531 {
00532 return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
00533 }
00534
00535 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
00536 {
00537 return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
00538 }
00539
00540 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
00541 {
00542 return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd);
00543 }
00544
00545 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
00546 {
00547 return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd);
00548 }
00549
00550 template <typename T>
00551 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
00552 {
00553 return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
00554 }
00555
00556 template <typename T>
00557 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
00558 {
00559 return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
00560 }
00561
00562 template <typename T>
00563 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
00564 {
00565 return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
00566 }
00567
00568 template <typename T>
00569 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
00570 {
00571 return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
00572 }
00573
00574 template <typename T>
00575 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
00576 {
00577 return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
00578 }
00579
00580 template <typename T>
00581 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
00582 {
00583 return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
00584 }
00585
00586 template <typename T>
00587 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
00588 {
00589 return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, newValue));
00590 }
00591 template <typename T>
00592 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
00593 {
00594 return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, newValue));
00595 }
00596
00597 template <typename T>
00598 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
00599 {
00600 return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, newValue));
00601 }
00602
00603 #endif // Q_CC_GNU
00604
00605 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00606 {
00607 return testAndSetAcquire(expectedValue, newValue);
00608 }
00609
00610 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00611 {
00612 return fetchAndStoreAcquire(newValue);
00613 }
00614
00615 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00616 {
00617 return fetchAndAddAcquire(valueToAdd);
00618 }
00619
00620 template <typename T>
00621 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00622 {
00623 return testAndSetAcquire(expectedValue, newValue);
00624 }
00625
00626 template <typename T>
00627 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00628 {
00629 return fetchAndStoreAcquire(newValue);
00630 }
00631
00632 template <typename T>
00633 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
00634 {
00635 return fetchAndAddAcquire(valueToAdd);
00636 }
00637
00638 QT_END_NAMESPACE
00639
00640 QT_END_HEADER
00641
00642 #endif // QATOMIC_ALPHA_H