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

系统编程

开发平台:

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_IA64_H
  38. #define QATOMIC_IA64_H
  39. QT_BEGIN_HEADER
  40. QT_BEGIN_NAMESPACE
  41. #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
  42. inline bool QBasicAtomicInt::isReferenceCountingNative()
  43. { return true; }
  44. inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
  45. { return false; }
  46. #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
  47. #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
  48. inline bool QBasicAtomicInt::isTestAndSetNative()
  49. { return true; }
  50. inline bool QBasicAtomicInt::isTestAndSetWaitFree()
  51. { return true; }
  52. #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  53. inline bool QBasicAtomicInt::isFetchAndStoreNative()
  54. { return true; }
  55. inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
  56. { return false; }
  57. #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  58. inline bool QBasicAtomicInt::isFetchAndAddNative()
  59. { return true; }
  60. inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
  61. { return false; }
  62. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
  63. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
  64. template <typename T>
  65. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
  66. { return true; }
  67. template <typename T>
  68. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
  69. { return true; }
  70. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  71. template <typename T>
  72. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
  73. { return true; }
  74. template <typename T>
  75. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
  76. { return false; }
  77. #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  78. template <typename T>
  79. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
  80. { return true; }
  81. template <typename T>
  82. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
  83. { return false; }
  84. #if defined(Q_CC_INTEL)
  85. // intrinsics provided by the Intel C++ Compiler
  86. #include <ia64intrin.h>
  87. inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
  88. {
  89.     register int expectedValueCopy = expectedValue;
  90.     return (static_cast<int>(_InterlockedCompareExchange(&_q_value, 
  91.  newValue, 
  92.  expectedValueCopy))
  93.     == expectedValue);
  94. }
  95. inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  96. {
  97.     register int expectedValueCopy = expectedValue;
  98.     return (static_cast<int>(_InterlockedCompareExchange_acq(reinterpret_cast<volatile uint *>(&_q_value), 
  99.      newValue, 
  100.      expectedValueCopy)) 
  101.     == expectedValue);
  102. }
  103. inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  104. {
  105.     register int expectedValueCopy = expectedValue;
  106.     return (static_cast<int>(_InterlockedCompareExchange_rel(reinterpret_cast<volatile uint *>(&_q_value), 
  107.      newValue, 
  108.      expectedValueCopy)) 
  109.     == expectedValue);
  110. }
  111. inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
  112. {
  113.     __memory_barrier();
  114.     return testAndSetAcquire(expectedValue, newValue);
  115. }
  116. template <typename T>
  117. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
  118. {
  119.     register T *expectedValueCopy = expectedValue;
  120.     return (_InterlockedCompareExchangePointer(reinterpret_cast<void * volatile*>(&_q_value), 
  121.        newValue, 
  122.        expectedValueCopy)
  123.     == expectedValue);
  124. }
  125. template <typename T>
  126. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  127. {
  128.     union {
  129.         volatile void *x;
  130.         volatile unsigned long *p;
  131.     };
  132.     x = &_q_value;
  133.     register T *expectedValueCopy = expectedValue;
  134.     return (_InterlockedCompareExchange64_acq(p, quintptr(newValue), quintptr(expectedValueCopy)) 
  135.     == quintptr(expectedValue));
  136. }
  137. template <typename T>
  138. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  139. {
  140.     union {
  141.         volatile void *x;
  142.         volatile unsigned long *p;
  143.     };
  144.     x = &_q_value;
  145.     register T *expectedValueCopy = expectedValue;
  146.     return (_InterlockedCompareExchange64_rel(p, quintptr(newValue), quintptr(expectedValueCopy))
  147.     == quintptr(expectedValue));
  148. }
  149. template <typename T>
  150. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  151. {
  152.     __memory_barrier();
  153.     return testAndSetAcquire(expectedValue, newValue);
  154. }
  155. #else // !Q_CC_INTEL
  156. #  if defined(Q_CC_GNU)
  157. inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  158. {
  159.     int ret;
  160.     asm volatile("mov ar.ccv=%2n"
  161.                  ";;n"
  162.                  "cmpxchg4.acq %0=%1,%3,ar.ccvn"
  163.                  : "=r" (ret), "+m" (_q_value)
  164.                  : "r" (expectedValue), "r" (newValue)
  165.                  : "memory");
  166.     return ret == expectedValue;
  167. }
  168. inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  169. {
  170.     int ret;
  171.     asm volatile("mov ar.ccv=%2n"
  172.                  ";;n"
  173.                  "cmpxchg4.rel %0=%1,%3,ar.ccvn"
  174.                  : "=r" (ret), "+m" (_q_value)
  175.                  : "r" (expectedValue), "r" (newValue)
  176.                  : "memory");
  177.     return ret == expectedValue;
  178. }
  179. template <typename T>
  180. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  181. {
  182.     T *ret;
  183.     asm volatile("mov ar.ccv=%2n"
  184.                  ";;n"
  185.                  "cmpxchg8.acq %0=%1,%3,ar.ccvn"
  186.                  : "=r" (ret), "+m" (_q_value)
  187.                  : "r" (expectedValue), "r" (newValue)
  188.                  : "memory");
  189.     return ret == expectedValue;
  190. }
  191. template <typename T>
  192. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  193. {
  194.     T *ret;
  195.     asm volatile("mov ar.ccv=%2n"
  196.                  ";;n"
  197.                  "cmpxchg8.rel %0=%1,%3,ar.ccvn"
  198.                  : "=r" (ret), "+m" (_q_value)
  199.                  : "r" (expectedValue), "r" (newValue)
  200.                  : "memory");
  201.     return ret == expectedValue;
  202. }
  203. #elif defined Q_CC_HPACC
  204. QT_BEGIN_INCLUDE_NAMESPACE
  205. #include <ia64/sys/inline.h>
  206. QT_END_INCLUDE_NAMESPACE
  207. #define FENCE (_Asm_fence)(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE)
  208. inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  209. {
  210.     _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE);
  211.     int ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ,
  212.                            &_q_value, (unsigned)newValue, (_Asm_ldhint)_LDHINT_NONE);
  213.     return ret == expectedValue;
  214. }
  215. inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  216. {
  217.     _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE);
  218.     int ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL,
  219.                            &_q_value, newValue, (_Asm_ldhint)_LDHINT_NONE);
  220.     return ret == expectedValue;
  221. }
  222. template <typename T>
  223. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  224. {
  225. #ifdef __LP64__
  226.     _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE);
  227.     T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ,
  228.                                &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE);
  229. #else
  230.     _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)expectedValue, FENCE);
  231.     T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ,
  232.                                &_q_value, (quint32)newValue, (_Asm_ldhint)_LDHINT_NONE);
  233. #endif
  234.     return ret == expectedValue;
  235. }
  236. template <typename T>
  237. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  238. {
  239. #ifdef __LP64__
  240.     _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE);
  241.     T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL,
  242.                                &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE);
  243. #else
  244.     _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)expectedValue, FENCE);
  245.     T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL,
  246.                                &_q_value, (quint32)newValue, (_Asm_ldhint)_LDHINT_NONE);
  247. #endif
  248.     return ret == expectedValue;
  249. }
  250. #else
  251. extern "C" {
  252.     Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
  253.     Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
  254. } // extern "C"
  255. #endif
  256. inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
  257. {
  258.     return testAndSetAcquire(expectedValue, newValue);
  259. }
  260. inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
  261. {
  262.     return testAndSetAcquire(expectedValue, newValue);
  263. }
  264. template <typename T>
  265. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
  266. {
  267.     return testAndSetAcquire(expectedValue, newValue);
  268. }
  269. template <typename T>
  270. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  271. {
  272.     return testAndSetAcquire(expectedValue, newValue);
  273. }
  274. #endif // Q_CC_INTEL
  275. inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
  276. {
  277.     int returnValue;
  278.     for (;;) {
  279.         returnValue = _q_value;
  280.         if (testAndSetRelaxed(returnValue, newValue))
  281.             break;
  282.     }
  283.     return returnValue;
  284. }
  285. inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
  286. {
  287.     int returnValue;
  288.     for (;;) {
  289.         returnValue = _q_value;
  290.         if (testAndSetAcquire(returnValue, newValue))
  291.             break;
  292.     }
  293.     return returnValue;
  294. }
  295. inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
  296. {
  297.     int returnValue;
  298.     for (;;) {
  299.         returnValue = _q_value;
  300.         if (testAndSetRelease(returnValue, newValue))
  301.             break;
  302.     }
  303.     return returnValue;
  304. }
  305. inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
  306. {
  307.     int returnValue;
  308.     for (;;) {
  309.         returnValue = _q_value;
  310.         if (testAndSetOrdered(returnValue, newValue))
  311.             break;
  312.     }
  313.     return returnValue;
  314. }
  315. inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
  316. {
  317.     int returnValue;
  318.     for (;;) {
  319.         returnValue = _q_value;
  320.         if (testAndSetRelaxed(returnValue, _q_value + valueToAdd))
  321.             break;
  322.     }
  323.     return returnValue;
  324. }
  325. inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
  326. {
  327.     int returnValue;
  328.     for (;;) {
  329.         returnValue = _q_value;
  330.         if (testAndSetAcquire(returnValue, _q_value + valueToAdd))
  331.             break;
  332.     }
  333.     return returnValue;
  334. }
  335. inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
  336. {
  337.     int returnValue;
  338.     for (;;) {
  339.         returnValue = _q_value;
  340.         if (testAndSetRelease(returnValue, _q_value + valueToAdd))
  341.             break;
  342.     }
  343.     return returnValue;
  344. }
  345. inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
  346. {
  347.     int returnValue;
  348.     for (;;) {
  349.         returnValue = _q_value;
  350.         if (testAndSetOrdered(returnValue, _q_value + valueToAdd))
  351.             break;
  352.     }
  353.     return returnValue;
  354. }
  355. inline bool QBasicAtomicInt::ref()
  356. {
  357.     return fetchAndAddRelaxed(1) != -1;
  358. }
  359. inline bool QBasicAtomicInt::deref()
  360. {
  361.     return fetchAndAddRelaxed(-1) != 1;
  362. }
  363. template <typename T>
  364. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
  365. {
  366.     T *returnValue;
  367.     for (;;) {
  368.         returnValue = (_q_value);
  369.         if (testAndSetRelaxed(returnValue, newValue))
  370.             break;
  371.     }
  372.     return returnValue;
  373. }
  374. template <typename T>
  375. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
  376. {
  377.     T *returnValue;
  378.     for (;;) {
  379.         returnValue = (_q_value);
  380.         if (testAndSetAcquire(returnValue, newValue))
  381.             break;
  382.     }
  383.     return returnValue;
  384. }
  385. template <typename T>
  386. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
  387. {
  388.     T *returnValue;
  389.     for (;;) {
  390.         returnValue = (_q_value);
  391.         if (testAndSetRelease(returnValue, newValue))
  392.             break;
  393.     }
  394.     return returnValue;
  395. }
  396. template <typename T>
  397. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
  398. {
  399.     T *returnValue;
  400.     for (;;) {
  401.         returnValue = (_q_value);
  402.         if (testAndSetOrdered(returnValue, newValue))
  403.             break;
  404.     }
  405.     return returnValue;
  406. }
  407. template <typename T>
  408. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
  409. {
  410.     T *returnValue;
  411.     for (;;) {
  412.         returnValue = (_q_value);
  413.         if (testAndSetRelaxed(returnValue, returnValue + valueToAdd))
  414.             break;
  415.     }
  416.     return returnValue;
  417. }
  418. template <typename T>
  419. Q_INLINE_TEMPLATE
  420. T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
  421. {
  422.     T *returnValue;
  423.     for (;;) {
  424.         returnValue = (_q_value);
  425.         if (testAndSetAcquire(returnValue, returnValue + valueToAdd))
  426.             break;
  427.     }
  428.     return returnValue;
  429. }
  430. template <typename T>
  431. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
  432. {
  433.     T *returnValue;
  434.     for (;;) {
  435.         returnValue = (_q_value);
  436.         if (testAndSetRelease(returnValue, returnValue + valueToAdd))
  437.             break;
  438.     }
  439.     return returnValue;
  440. }
  441. template <typename T>
  442. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
  443. {
  444.     T *returnValue;
  445.     for (;;) {
  446.         returnValue = (_q_value);
  447.         if (testAndSetOrdered(returnValue, returnValue + valueToAdd))
  448.             break;
  449.     }
  450.     return returnValue;
  451. }
  452. QT_END_NAMESPACE
  453. QT_END_HEADER
  454. #endif // QATOMIC_IA64_H