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

系统编程

开发平台:

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_S390_H
  38. #define QATOMIC_S390_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. inline bool QBasicAtomicInt::isTestAndSetNative()
  48. { return true; }
  49. inline bool QBasicAtomicInt::isTestAndSetWaitFree()
  50. { return false; }
  51. #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  52. inline bool QBasicAtomicInt::isFetchAndStoreNative()
  53. { return true; }
  54. inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
  55. { return false; }
  56. #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  57. inline bool QBasicAtomicInt::isFetchAndAddNative()
  58. { return true; }
  59. inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
  60. { return false; }
  61. #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
  62. template <typename T>
  63. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
  64. { return true; }
  65. template <typename T>
  66. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
  67. { return false; }
  68. #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
  69. template <typename T>
  70. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
  71. { return true; }
  72. template <typename T>
  73. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
  74. { return false; }
  75. #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
  76. template <typename T>
  77. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
  78. { return true; }
  79. template <typename T>
  80. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
  81. { return false; }
  82. #ifdef __GNUC__
  83. #define __GNU_EXTENSION __extension__
  84. #else
  85. #define __GNU_EXTENSION
  86. #endif
  87. #define __CS_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({   
  88. volatile int old_val, new_val;
  89.         __asm__ __volatile__(pre                                        
  90.                              "   l     %0,0(%3)n"                      
  91.                              "0: lr    %1,%0n"
  92.                              op_string "  %1,%4n"
  93.                              "   cs    %0,%1,0(%3)n"
  94.                              "   jl    0bn"
  95.                              post                                       
  96.                              : "=&d" (old_val), "=&d" (new_val),
  97.        "=m" (*ptr)
  98.      : "a" (ptr), "d" (op_val),
  99.        "m" (*ptr)
  100.      : "cc", "memory" );
  101. new_val;
  102. })
  103. #define __CS_OLD_LOOP(ptr, op_val, op_string, pre, post ) __GNU_EXTENSION ({ 
  104. volatile int old_val, new_val;
  105.         __asm__ __volatile__(pre                                        
  106.                              "   l     %0,0(%3)n"
  107.                              "0: lr    %1,%0n"
  108.                              op_string "  %1,%4n"
  109.                              "   cs    %0,%1,0(%3)n"
  110.                              "   jl    0bn"
  111.                              post                                       
  112.                              : "=&d" (old_val), "=&d" (new_val),
  113.        "=m" (*ptr)
  114.      : "a" (ptr), "d" (op_val),
  115.        "m" (*ptr)
  116.      : "cc", "memory" );
  117. old_val;
  118. })
  119. #ifdef __s390x__
  120. #define __CSG_OLD_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ 
  121. long old_val, new_val;
  122.         __asm__ __volatile__(pre                                        
  123.                              "   lg    %0,0(%3)n"                      
  124.                              "0: lgr   %1,%0n"
  125.                              op_string "  %1,%4n"
  126.                              "   csg   %0,%1,0(%3)n"
  127.                              "   jl    0bn"
  128.                              post                                       
  129.                              : "=&d" (old_val), "=&d" (new_val),
  130.        "=m" (*ptr)
  131.      : "a" (ptr), "d" (op_val),
  132.        "m" (*ptr)
  133.      : "cc", "memory" );
  134. old_val;
  135. })
  136. #endif
  137. inline bool QBasicAtomicInt::ref()
  138. {
  139.     return __CS_LOOP(&_q_value, 1, "ar", "", "") != 0;
  140. }
  141. inline bool QBasicAtomicInt::deref()
  142. {
  143.     return __CS_LOOP(&_q_value, 1, "sr", "", "") != 0;
  144. }
  145. inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
  146. {
  147.     int retval;
  148.     __asm__ __volatile__(
  149.                          "  lr   %0,%3n"
  150.                          "  cs   %0,%4,0(%2)n"
  151.                          "  ipm  %0n"
  152.                          "  srl  %0,28n"
  153.                          "0:"
  154.                          : "=&d" (retval), "=m" (_q_value)
  155.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  156.                            "m" (_q_value) : "cc", "memory" );
  157.     return retval == 0;
  158. }
  159. inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
  160. {
  161.     int retval;
  162.     __asm__ __volatile__(
  163.                          "  lr   %0,%3n"
  164.                          "  cs   %0,%4,0(%2)n"
  165.                          "  ipm  %0n"
  166.                          "  srl  %0,28n"
  167.                          "0:n"
  168.                          "  bcr 15,0n"
  169.                          : "=&d" (retval), "=m" (_q_value)
  170.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  171.                            "m" (_q_value) : "cc", "memory" );
  172.     return retval == 0;
  173. }
  174. inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
  175. {
  176.     int retval;
  177.     __asm__ __volatile__(
  178.                          "  bcr 15,0n"
  179.                          "  lr   %0,%3n"
  180.                          "  cs   %0,%4,0(%2)n"
  181.                          "  ipm  %0n"
  182.                          "  srl  %0,28n"
  183.                          "0:"
  184.                          : "=&d" (retval), "=m" (_q_value)
  185.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  186.                            "m" (_q_value) : "cc", "memory" );
  187.     return retval == 0;
  188. }
  189. inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
  190. {
  191.     return testAndSetAcquire(expectedValue, newValue);
  192. }
  193. inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
  194. {
  195.     return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "");
  196. }
  197. inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
  198. {
  199.     return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "bcr 15,0n");
  200. }
  201. inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
  202. {
  203.     return __CS_OLD_LOOP(&_q_value, newValue, "lr", "bcr 15,0n", "");
  204. }
  205. inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
  206. {
  207.     return fetchAndStoreAcquire(newValue);
  208. }
  209. inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
  210. {
  211.     return fetchAndAddOrdered(valueToAdd);
  212. }
  213. inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
  214. {
  215.     return fetchAndAddOrdered(valueToAdd);
  216. }
  217. inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
  218. {
  219.     return fetchAndAddOrdered(valueToAdd);
  220. }
  221. inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
  222. {
  223.     return __CS_OLD_LOOP(&_q_value, valueToAdd, "ar", "", "bcr 15,0n");
  224. }
  225. template <typename T>
  226. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
  227. {
  228.     int retval;
  229. #ifndef __s390x__
  230.     __asm__ __volatile__(
  231.                          "  lr   %0,%3n"
  232.                          "  cs   %0,%4,0(%2)n"
  233.                          "  ipm  %0n"
  234.                          "  srl  %0,28n"
  235.                          "0:"
  236.                          : "=&d" (retval), "=m" (_q_value)
  237.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  238.                            "m" (_q_value) : "cc", "memory" );
  239. #else
  240.     __asm__ __volatile__(
  241.                          "  lgr   %0,%3n"
  242.                          "  csg   %0,%4,0(%2)n"
  243.                          "  ipm  %0n"
  244.                          "  srl  %0,28n"
  245.                          "0:"
  246.                          : "=&d" (retval), "=m" (_q_value)
  247.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  248.                            "m" (_q_value) : "cc", "memory" );
  249. #endif
  250.     return retval == 0;
  251. }
  252. template <typename T>
  253. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
  254. {
  255.     int retval;
  256. #ifndef __s390x__
  257.     __asm__ __volatile__(
  258.                          "  lr   %0,%3n"
  259.                          "  cs   %0,%4,0(%2)n"
  260.                          "  ipm  %0n"
  261.                          "  srl  %0,28n"
  262.                          "0:n"
  263.                          "  bcr 15,0n"
  264.                          : "=&d" (retval), "=m" (_q_value)
  265.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  266.                            "m" (_q_value) : "cc", "memory" );
  267. #else
  268.     __asm__ __volatile__(
  269.                          "  lgr   %0,%3n"
  270.                          "  csg   %0,%4,0(%2)n"
  271.                          "  ipm  %0n"
  272.                          "  srl  %0,28n"
  273.                          "0:n"
  274.                          "  bcr 15,0n"
  275.                          : "=&d" (retval), "=m" (_q_value)
  276.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  277.                            "m" (_q_value) : "cc", "memory" );
  278. #endif
  279.     return retval == 0;
  280. }
  281. template <typename T>
  282. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
  283. {
  284.     int retval;
  285. #ifndef __s390x__
  286.     __asm__ __volatile__(
  287.                          "  bcr 15,0n"
  288.                          "  lr   %0,%3n"
  289.                          "  cs   %0,%4,0(%2)n"
  290.                          "  ipm  %0n"
  291.                          "  srl  %0,28n"
  292.                          "0:"
  293.                          : "=&d" (retval), "=m" (_q_value)
  294.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  295.                            "m" (_q_value) : "cc", "memory" );
  296. #else
  297.     __asm__ __volatile__(
  298.                          "  bcr 15,0n"
  299.                          "  lgr   %0,%3n"
  300.                          "  csg   %0,%4,0(%2)n"
  301.                          "  ipm  %0n"
  302.                          "  srl  %0,28n"
  303.                          "0:"
  304.                          : "=&d" (retval), "=m" (_q_value)
  305.                          : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
  306.                            "m" (_q_value) : "cc", "memory" );
  307. #endif
  308.     return retval == 0;
  309. }
  310. template <typename T>
  311. Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
  312. {
  313.     return testAndSetAcquire(expectedValue, newValue);
  314. }
  315. template <typename T>
  316. Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
  317. {
  318. #ifndef __s390x__
  319.     return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
  320.                              "", "bcr 15,0n");
  321. #else
  322.     return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
  323.                               "", "bcr 15,0n");
  324. #endif
  325. }
  326. template <typename T>
  327. Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
  328. {
  329. #ifndef __s390x__
  330.     return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr", "", "");
  331. #else
  332.     return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr", "", "");
  333. #endif
  334. }
  335. template <typename T>
  336. Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
  337. {
  338. #ifndef __s390x__
  339.     return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
  340.                              "bcr 15,0 n", "");
  341. #else
  342.     return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
  343.                               "bcr 15,0n", "");
  344. #endif
  345. }
  346. template <typename T>
  347. Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
  348. {
  349.     return fetchAndStoreAcquire(newValue);
  350. }
  351. template <typename T>
  352. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
  353. {
  354.     return fetchAndAddOrdered(valueToAdd);
  355. }
  356. template <typename T>
  357. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
  358. {
  359.     return fetchAndAddOrdered(valueToAdd);
  360. }
  361. template <typename T>
  362. Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
  363. {
  364.     return fetchAndAddOrdered(valueToAdd);
  365. }
  366. #undef __GNU_EXTENSION
  367. QT_END_NAMESPACE
  368. QT_END_HEADER
  369. #endif // QATOMIC_S390_H