qatomic_sparc.h
上传用户:detong
上传日期:2022-06-22
资源大小:20675k
文件大小:16k
源码类别:

系统编程

开发平台:

Unix_Linux

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  4. ** Contact: Qt Software Information (qt-info@nokia.com)
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #ifndef QATOMIC_SPARC_H
  38. #define QATOMIC_SPARC_H
  39. QT_BEGIN_HEADER
  40. QT_BEGIN_NAMESPACE
  41. #if defined(_LP64)
  42. #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
  43. inline bool QBasicAtomicInt::isReferenceCountingNative()
  44. { return true; }
  45. inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
  46. { return false; }
  47. #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
  48. #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
  49. inline bool QBasicAtomicInt::isTestAndSetNative()
  50. { return true; }
  51. inline bool QBasicAtomicInt::isTestAndSetWaitFree()
  52. { return true; }
  53. #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  54. #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
  55. inline bool QBasicAtomicInt::isFetchAndStoreNative()
  56. { return true; }
  57. inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
  58. { return true; }
  59. #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  60. inline bool QBasicAtomicInt::isFetchAndAddNative()
  61. { return true; }
  62. inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
  63. { return false; }
  64. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
  65. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
  66. template <typename T>
  67. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
  68. { return true; }
  69. template <typename T>
  70. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
  71. { return true; }
  72. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  73. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
  74. template <typename T>
  75. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
  76. { return true; }
  77. template <typename T>
  78. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
  79. { return true; }
  80. #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  81. template <typename T>
  82. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
  83. { return true; }
  84. template <typename T>
  85. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
  86. { return false; }
  87. extern "C" {
  88.     Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
  89.     Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
  90.     Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
  91.     Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr,
  92.                                                         int expected,
  93.                                                         int newval);
  94.     Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr,
  95.                                                         int expected,
  96.                                                         int newval);
  97.     Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
  98.     Q_CORE_EXPORT int q_atomic_fetch_and_store_acquire_int(volatile int *ptr, int newval);
  99.     Q_CORE_EXPORT int q_atomic_fetch_and_store_release_int(volatile int *ptr, int newval);
  100.     Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
  101.     Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
  102.     Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value);
  103.     Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
  104.     Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr,
  105.                                                         void *expected,
  106.                                                         void *newval);
  107.     Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr,
  108.                                                         void *expected,
  109.                                                         void *newval);
  110.     Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
  111.     Q_CORE_EXPORT void *q_atomic_fetch_and_store_acquire_ptr(volatile void *ptr, void *newval);
  112.     Q_CORE_EXPORT void *q_atomic_fetch_and_store_release_ptr(volatile void *ptr, void *newval);
  113.     Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, int value);
  114.     Q_CORE_EXPORT void *q_atomic_fetch_and_add_acquire_ptr(volatile void *ptr, int value);
  115.     Q_CORE_EXPORT void *q_atomic_fetch_and_add_release_ptr(volatile void *ptr, int value);
  116. }
  117. inline bool QBasicAtomicInt::ref()
  118. {
  119.     return fetchAndAddRelaxed(1) != -1;
  120. }
  121. inline bool QBasicAtomicInt::deref()
  122. {
  123.     return fetchAndAddRelaxed(-1) != 1;
  124. }
  125. inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
  126. {
  127.     return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
  128. }
  129. inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  130. {
  131.     return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
  132. }
  133. inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  134. {
  135.     return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
  136. }
  137. inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
  138. {
  139.     return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
  140. }
  141. inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
  142. {
  143.     return q_atomic_set_int(&_q_value, newValue);
  144. }
  145. inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
  146. {
  147.     return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
  148. }
  149. inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
  150. {
  151.     return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
  152. }
  153. inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
  154. {
  155.     return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
  156. }
  157. inline int QBasicAtomicInt::fetchAndAddRelaxed(int newValue)
  158. {
  159.     return q_atomic_fetch_and_add_int(&_q_value, newValue);
  160. }
  161. inline int QBasicAtomicInt::fetchAndAddAcquire(int newValue)
  162. {
  163.     return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue);
  164. }
  165. inline int QBasicAtomicInt::fetchAndAddRelease(int newValue)
  166. {
  167.     return q_atomic_fetch_and_add_release_int(&_q_value, newValue);
  168. }
  169. inline int QBasicAtomicInt::fetchAndAddOrdered(int newValue)
  170. {
  171.     return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue);
  172. }
  173. template <typename T>
  174. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
  175. {
  176.     return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
  177. }
  178. template <typename T>
  179. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  180. {
  181.     return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
  182. }
  183. template <typename T>
  184. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  185. {
  186.     return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
  187. }
  188. template <typename T>
  189. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  190. {
  191.     return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
  192. }
  193. template <typename T>
  194. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
  195. {
  196.     return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
  197. }
  198. template <typename T>
  199. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
  200. {
  201.     return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
  202. }
  203. template <typename T>
  204. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
  205. {
  206.     return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
  207. }
  208. template <typename T>
  209. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
  210. {
  211.     return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
  212. }
  213. template <typename T>
  214. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
  215. {
  216.     return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
  217. }
  218. template <typename T>
  219. Q_INLINE_TEMPLATE
  220. T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
  221. {
  222.     return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
  223. }
  224. template <typename T>
  225. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
  226. {
  227.     return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, valueToAdd * sizeof(T)));
  228. }
  229. template <typename T>
  230. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
  231. {
  232.     return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
  233. }
  234. #else
  235. #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
  236. inline bool QBasicAtomicInt::isReferenceCountingNative()
  237. { return false; }
  238. inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
  239. { return false; }
  240. #define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
  241. inline bool QBasicAtomicInt::isTestAndSetNative()
  242. { return false; }
  243. inline bool QBasicAtomicInt::isTestAndSetWaitFree()
  244. { return false; }
  245. #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  246. #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
  247. inline bool QBasicAtomicInt::isFetchAndStoreNative()
  248. { return true; }
  249. inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
  250. { return true; }
  251. #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
  252. inline bool QBasicAtomicInt::isFetchAndAddNative()
  253. { return false; }
  254. inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
  255. { return false; }
  256. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
  257. template <typename T>
  258. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
  259. { return false; }
  260. template <typename T>
  261. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
  262. { return false; }
  263. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  264. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
  265. template <typename T>
  266. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
  267. { return true; }
  268. template <typename T>
  269. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
  270. { return true; }
  271. #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
  272. template <typename T>
  273. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
  274. { return false; }
  275. template <typename T>
  276. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
  277. { return false; }
  278. extern "C" {
  279.     Q_CORE_EXPORT int q_atomic_lock_int(volatile int *addr);
  280.     Q_CORE_EXPORT int q_atomic_lock_ptr(volatile void *addr);
  281.     Q_CORE_EXPORT void q_atomic_unlock(volatile void *addr, int value);
  282.     Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
  283.     Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
  284. } // extern "C"
  285. inline bool QBasicAtomicInt::ref()
  286. {
  287.     const int val = q_atomic_lock_int(&_q_value);
  288.     q_atomic_unlock(&_q_value, val + 1);
  289.     return val != -1;
  290. }
  291. inline bool QBasicAtomicInt::deref()
  292. {
  293.     const int val = q_atomic_lock_int(&_q_value);
  294.     q_atomic_unlock(&_q_value, val - 1);
  295.     return val != 1;
  296. }
  297. inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
  298. {
  299.     int val = q_atomic_lock_int(&_q_value);
  300.     if (val == expectedValue) {
  301.         q_atomic_unlock(&_q_value, newValue);
  302.         return true;
  303.     }
  304.     q_atomic_unlock(&_q_value, val);
  305.     return false;
  306. }
  307. inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
  308. {
  309.     return testAndSetOrdered(expectedValue, newValue);
  310. }
  311. inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  312. {
  313.     return testAndSetOrdered(expectedValue, newValue);
  314. }
  315. inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  316. {
  317.     return testAndSetOrdered(expectedValue, newValue);
  318. }
  319. inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
  320. {
  321.     return q_atomic_set_int(&_q_value, newValue);
  322. }
  323. inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
  324. {
  325.     return fetchAndStoreOrdered(newValue);
  326. }
  327. inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
  328. {
  329.     return fetchAndStoreOrdered(newValue);
  330. }
  331. inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
  332. {
  333.     return fetchAndStoreOrdered(newValue);
  334. }
  335. inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
  336. {
  337.     const int originalValue = q_atomic_lock_int(&_q_value);
  338.     q_atomic_unlock(&_q_value, originalValue + valueToAdd);
  339.     return originalValue;
  340. }
  341. inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
  342. {
  343.     return fetchAndAddOrdered(valueToAdd);
  344. }
  345. inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
  346. {
  347.     return fetchAndAddOrdered(valueToAdd);
  348. }
  349. inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
  350. {
  351.     return fetchAndAddOrdered(valueToAdd);
  352. }
  353. template <typename T>
  354. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  355. {
  356.     T *val = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value));
  357.     if (val == expectedValue) {
  358.         q_atomic_unlock(&_q_value, reinterpret_cast<int>(newValue));
  359.         return true;
  360.     }
  361.     q_atomic_unlock(&_q_value, reinterpret_cast<int>(val));
  362.     return false;
  363. }
  364. template <typename T>
  365. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
  366. {
  367.     return testAndSetOrdered(expectedValue, newValue);
  368. }
  369. template <typename T>
  370. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  371. {
  372.     return testAndSetOrdered(expectedValue, newValue);
  373. }
  374. template <typename T>
  375. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  376. {
  377.     return testAndSetOrdered(expectedValue, newValue);
  378. }
  379. template <typename T>
  380. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
  381. {
  382.     return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
  383. }
  384. template <typename T>
  385. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
  386. {
  387.     return fetchAndStoreOrdered(newValue);
  388. }
  389. template <typename T>
  390. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
  391. {
  392.     return fetchAndStoreOrdered(newValue);
  393. }
  394. template <typename T>
  395. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
  396. {
  397.     return fetchAndStoreOrdered(newValue);
  398. }
  399. template <typename T>
  400. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
  401. {
  402.     T *originalValue = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value));
  403.     q_atomic_unlock(&_q_value, int(originalValue + valueToAdd));
  404.     return originalValue;
  405. }
  406. template <typename T>
  407. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
  408. {
  409.     return fetchAndAddOrdered(valueToAdd);
  410. }
  411. template <typename T>
  412. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
  413. {
  414.     return fetchAndAddOrdered(valueToAdd);
  415. }
  416. template <typename T>
  417. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
  418. {
  419.     return fetchAndAddOrdered(valueToAdd);
  420. }
  421. #endif // _LP64
  422. QT_END_NAMESPACE
  423. QT_END_HEADER
  424. #endif // QATOMIC_SPARC_H