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