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

系统编程

开发平台:

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_X86_64_H
  38. #define QATOMIC_X86_64_H
  39. QT_BEGIN_HEADER
  40. QT_BEGIN_NAMESPACE
  41. #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
  42. #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
  43. inline bool QBasicAtomicInt::isReferenceCountingNative()
  44. { return true; }
  45. inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
  46. { return true; }
  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. #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
  61. inline bool QBasicAtomicInt::isFetchAndAddNative()
  62. { return true; }
  63. inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
  64. { return true; }
  65. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
  66. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
  67. template <typename T>
  68. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
  69. { return true; }
  70. template <typename T>
  71. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
  72. { return true; }
  73. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  74. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
  75. template <typename T>
  76. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
  77. { return true; }
  78. template <typename T>
  79. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
  80. { return true; }
  81. #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  82. #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
  83. template <typename T>
  84. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
  85. { return true; }
  86. template <typename T>
  87. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
  88. { return true; }
  89. #if defined(Q_CC_GNU) || defined(Q_CC_INTEL)
  90. inline bool QBasicAtomicInt::ref()
  91. {
  92.     unsigned char ret;
  93.     asm volatile("lockn"
  94.                  "incl %0n"
  95.                  "setne %1"
  96.                  : "=m" (_q_value), "=qm" (ret)
  97.                  : "m" (_q_value)
  98.                  : "memory");
  99.     return ret != 0;
  100. }
  101. inline bool QBasicAtomicInt::deref()
  102. {
  103.     unsigned char ret;
  104.     asm volatile("lockn"
  105.                  "decl %0n"
  106.                  "setne %1"
  107.                  : "=m" (_q_value), "=qm" (ret)
  108.                  : "m" (_q_value)
  109.                  : "memory");
  110.     return ret != 0;
  111. }
  112. inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
  113. {
  114.     unsigned char ret;
  115.     asm volatile("lockn"
  116.                  "cmpxchgl %3,%2n"
  117.                  "sete %1n"
  118.                  : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
  119.                  : "r" (newValue), "0" (expectedValue)
  120.                  : "memory");
  121.     return ret != 0;
  122. }
  123. inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
  124. {
  125.     asm volatile("xchgl %0,%1"
  126.                  : "=r" (newValue), "+m" (_q_value)
  127.                  : "0" (newValue)
  128.                  : "memory");
  129.     return newValue;
  130. }
  131. inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
  132. {
  133.     asm volatile("lockn"
  134.                  "xaddl %0,%1"
  135.                  : "=r" (valueToAdd), "+m" (_q_value)
  136.                  : "0" (valueToAdd)
  137.                  : "memory");
  138.     return valueToAdd;
  139. }
  140. template <typename T>
  141. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  142. {
  143.     unsigned char ret;
  144.     asm volatile("lockn"
  145.                  "cmpxchgq %3,%2n"
  146.                  "sete %1n"
  147.                  : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
  148.                  : "r" (newValue), "0" (expectedValue)
  149.                  : "memory");
  150.     return ret != 0;
  151. }
  152. template <typename T>
  153. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
  154. {
  155.     asm volatile("xchgq %0,%1"
  156.                  : "=r" (newValue), "+m" (_q_value)
  157.                  : "0" (newValue)
  158.                  : "memory");
  159.     return newValue;
  160. }
  161. template <typename T>
  162. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
  163. {
  164.     asm volatile("lockn"
  165.                  "xaddq %0,%1"
  166.                  : "=r" (valueToAdd), "+m" (_q_value)
  167.                  : "0" (valueToAdd * sizeof(T))
  168.                  : "memory");
  169.     return reinterpret_cast<T *>(valueToAdd);
  170. }
  171. #else // !Q_CC_INTEL && !Q_CC_GNU
  172. extern "C" {
  173.     Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
  174.     Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
  175.     Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
  176.     Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
  177.     Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
  178.     Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
  179.     Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
  180.     Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, qptrdiff value);
  181. } // extern "C"
  182. inline bool QBasicAtomicInt::ref()
  183. {
  184.     return q_atomic_increment(&_q_value) != 0;
  185. }
  186. inline bool QBasicAtomicInt::deref()
  187. {
  188.     return q_atomic_decrement(&_q_value) != 0;
  189. }
  190. inline bool QBasicAtomicInt::testAndSetOrdered(int expected, int newval)
  191. {
  192.     return q_atomic_test_and_set_int(&_q_value, expected, newval) != 0;
  193. }
  194. inline int QBasicAtomicInt::fetchAndStoreOrdered(int newval)
  195. {
  196.     return q_atomic_set_int(&_q_value, newval);
  197. }
  198. inline int QBasicAtomicInt::fetchAndAddOrdered(int aValue)
  199. {
  200.     return q_atomic_fetch_and_add_int(&_q_value, aValue);
  201. }
  202. template <typename T>
  203. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  204. {
  205.     return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue);
  206. }
  207. template <typename T>
  208. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
  209. {
  210.     return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
  211. }
  212. template <typename T>
  213. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
  214. {
  215.     return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
  216. }
  217. #endif // Q_CC_GNU || Q_CC_INTEL
  218. inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
  219. {
  220.     return testAndSetOrdered(expectedValue, newValue);
  221. }
  222. inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  223. {
  224.     return testAndSetOrdered(expectedValue, newValue);
  225. }
  226. inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  227. {
  228.     return testAndSetOrdered(expectedValue, newValue);
  229. }
  230. inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
  231. {
  232.     return fetchAndStoreOrdered(newValue);
  233. }
  234. inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
  235. {
  236.     return fetchAndStoreOrdered(newValue);
  237. }
  238. inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
  239. {
  240.     return fetchAndStoreOrdered(newValue);
  241. }
  242. inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
  243. {
  244.     return fetchAndAddOrdered(valueToAdd);
  245. }
  246. inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
  247. {
  248.     return fetchAndAddOrdered(valueToAdd);
  249. }
  250. inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
  251. {
  252.     return fetchAndAddOrdered(valueToAdd);
  253. }
  254. template <typename T>
  255. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
  256. {
  257.     return testAndSetOrdered(expectedValue, newValue);
  258. }
  259. template <typename T>
  260. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  261. {
  262.     return testAndSetOrdered(expectedValue, newValue);
  263. }
  264. template <typename T>
  265. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  266. {
  267.     return testAndSetOrdered(expectedValue, newValue);
  268. }
  269. template <typename T>
  270. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
  271. {
  272.     return fetchAndStoreOrdered(newValue);
  273. }
  274. template <typename T>
  275. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
  276. {
  277.     return fetchAndStoreOrdered(newValue);
  278. }
  279. template <typename T>
  280. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
  281. {
  282.     return fetchAndStoreOrdered(newValue);
  283. }
  284. template <typename T>
  285. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
  286. {
  287.     return fetchAndAddOrdered(valueToAdd);
  288. }
  289. template <typename T>
  290. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
  291. {
  292.     return fetchAndAddOrdered(valueToAdd);
  293. }
  294. template <typename T>
  295. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
  296. {
  297.     return fetchAndAddOrdered(valueToAdd);
  298. }
  299. QT_END_NAMESPACE
  300. QT_END_HEADER
  301. #endif // QATOMIC_X86_64_H