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_S390_H
00043 #define QATOMIC_S390_H
00044
00045 QT_BEGIN_HEADER
00046
00047 QT_BEGIN_NAMESPACE
00048
00049 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
00050
00051 inline bool QBasicAtomicInt::isReferenceCountingNative()
00052 { return true; }
00053 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
00054 { return false; }
00055
00056 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
00057
00058 inline bool QBasicAtomicInt::isTestAndSetNative()
00059 { return true; }
00060 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
00061 { return false; }
00062
00063 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00064
00065 inline bool QBasicAtomicInt::isFetchAndStoreNative()
00066 { return true; }
00067 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
00068 { return false; }
00069
00070 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00071
00072 inline bool QBasicAtomicInt::isFetchAndAddNative()
00073 { return true; }
00074 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
00075 { return false; }
00076
00077 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
00078
00079 template <typename T>
00080 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
00081 { return true; }
00082 template <typename T>
00083 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
00084 { return false; }
00085
00086 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
00087
00088 template <typename T>
00089 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
00090 { return true; }
00091 template <typename T>
00092 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
00093 { return false; }
00094
00095 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
00096
00097 template <typename T>
00098 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
00099 { return true; }
00100 template <typename T>
00101 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
00102 { return false; }
00103
00104 #ifdef __GNUC__
00105 #define __GNU_EXTENSION __extension__
00106 #else
00107 #define __GNU_EXTENSION
00108 #endif
00109
00110 #define __CS_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
00111 volatile int old_val, new_val; \
00112 __asm__ __volatile__(pre \
00113 " l %0,0(%3)\n" \
00114 "0: lr %1,%0\n" \
00115 op_string " %1,%4\n" \
00116 " cs %0,%1,0(%3)\n" \
00117 " jl 0b\n" \
00118 post \
00119 : "=&d" (old_val), "=&d" (new_val), \
00120 "=m" (*ptr) \
00121 : "a" (ptr), "d" (op_val), \
00122 "m" (*ptr) \
00123 : "cc", "memory" ); \
00124 new_val; \
00125 })
00126
00127 #define __CS_OLD_LOOP(ptr, op_val, op_string, pre, post ) __GNU_EXTENSION ({ \
00128 volatile int old_val, new_val; \
00129 __asm__ __volatile__(pre \
00130 " l %0,0(%3)\n" \
00131 "0: lr %1,%0\n" \
00132 op_string " %1,%4\n" \
00133 " cs %0,%1,0(%3)\n" \
00134 " jl 0b\n" \
00135 post \
00136 : "=&d" (old_val), "=&d" (new_val), \
00137 "=m" (*ptr) \
00138 : "a" (ptr), "d" (op_val), \
00139 "m" (*ptr) \
00140 : "cc", "memory" ); \
00141 old_val; \
00142 })
00143
00144 #ifdef __s390x__
00145 #define __CSG_OLD_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
00146 long old_val, new_val; \
00147 __asm__ __volatile__(pre \
00148 " lg %0,0(%3)\n" \
00149 "0: lgr %1,%0\n" \
00150 op_string " %1,%4\n" \
00151 " csg %0,%1,0(%3)\n" \
00152 " jl 0b\n" \
00153 post \
00154 : "=&d" (old_val), "=&d" (new_val), \
00155 "=m" (*ptr) \
00156 : "a" (ptr), "d" (op_val), \
00157 "m" (*ptr) \
00158 : "cc", "memory" ); \
00159 old_val; \
00160 })
00161 #endif
00162
00163 inline bool QBasicAtomicInt::ref()
00164 {
00165 return __CS_LOOP(&_q_value, 1, "ar", "", "") != 0;
00166 }
00167
00168 inline bool QBasicAtomicInt::deref()
00169 {
00170 return __CS_LOOP(&_q_value, 1, "sr", "", "") != 0;
00171 }
00172
00173 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
00174 {
00175 int retval;
00176 __asm__ __volatile__(
00177 " lr %0,%3\n"
00178 " cs %0,%4,0(%2)\n"
00179 " ipm %0\n"
00180 " srl %0,28\n"
00181 "0:"
00182 : "=&d" (retval), "=m" (_q_value)
00183 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00184 "m" (_q_value) : "cc", "memory" );
00185 return retval == 0;
00186 }
00187
00188 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
00189 {
00190 int retval;
00191 __asm__ __volatile__(
00192 " lr %0,%3\n"
00193 " cs %0,%4,0(%2)\n"
00194 " ipm %0\n"
00195 " srl %0,28\n"
00196 "0:\n"
00197 " bcr 15,0\n"
00198 : "=&d" (retval), "=m" (_q_value)
00199 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00200 "m" (_q_value) : "cc", "memory" );
00201 return retval == 0;
00202 }
00203
00204 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
00205 {
00206 int retval;
00207 __asm__ __volatile__(
00208 " bcr 15,0\n"
00209 " lr %0,%3\n"
00210 " cs %0,%4,0(%2)\n"
00211 " ipm %0\n"
00212 " srl %0,28\n"
00213 "0:"
00214 : "=&d" (retval), "=m" (_q_value)
00215 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00216 "m" (_q_value) : "cc", "memory" );
00217 return retval == 0;
00218 }
00219
00220 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
00221 {
00222 return testAndSetAcquire(expectedValue, newValue);
00223 }
00224
00225 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
00226 {
00227 return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "");
00228 }
00229
00230 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
00231 {
00232 return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "bcr 15,0\n");
00233 }
00234
00235 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
00236 {
00237 return __CS_OLD_LOOP(&_q_value, newValue, "lr", "bcr 15,0\n", "");
00238 }
00239
00240 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
00241 {
00242 return fetchAndStoreAcquire(newValue);
00243 }
00244
00245 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
00246 {
00247 return fetchAndAddOrdered(valueToAdd);
00248 }
00249
00250 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
00251 {
00252 return fetchAndAddOrdered(valueToAdd);
00253 }
00254
00255 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
00256 {
00257 return fetchAndAddOrdered(valueToAdd);
00258 }
00259
00260 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
00261 {
00262 return __CS_OLD_LOOP(&_q_value, valueToAdd, "ar", "", "bcr 15,0\n");
00263 }
00264
00265 template <typename T>
00266 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
00267 {
00268 int retval;
00269
00270 #ifndef __s390x__
00271 __asm__ __volatile__(
00272 " lr %0,%3\n"
00273 " cs %0,%4,0(%2)\n"
00274 " ipm %0\n"
00275 " srl %0,28\n"
00276 "0:"
00277 : "=&d" (retval), "=m" (_q_value)
00278 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00279 "m" (_q_value) : "cc", "memory" );
00280 #else
00281 __asm__ __volatile__(
00282 " lgr %0,%3\n"
00283 " csg %0,%4,0(%2)\n"
00284 " ipm %0\n"
00285 " srl %0,28\n"
00286 "0:"
00287 : "=&d" (retval), "=m" (_q_value)
00288 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00289 "m" (_q_value) : "cc", "memory" );
00290 #endif
00291
00292 return retval == 0;
00293 }
00294
00295 template <typename T>
00296 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
00297 {
00298 int retval;
00299
00300 #ifndef __s390x__
00301 __asm__ __volatile__(
00302 " lr %0,%3\n"
00303 " cs %0,%4,0(%2)\n"
00304 " ipm %0\n"
00305 " srl %0,28\n"
00306 "0:\n"
00307 " bcr 15,0\n"
00308 : "=&d" (retval), "=m" (_q_value)
00309 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00310 "m" (_q_value) : "cc", "memory" );
00311 #else
00312 __asm__ __volatile__(
00313 " lgr %0,%3\n"
00314 " csg %0,%4,0(%2)\n"
00315 " ipm %0\n"
00316 " srl %0,28\n"
00317 "0:\n"
00318 " bcr 15,0\n"
00319 : "=&d" (retval), "=m" (_q_value)
00320 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00321 "m" (_q_value) : "cc", "memory" );
00322 #endif
00323
00324 return retval == 0;
00325 }
00326
00327 template <typename T>
00328 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
00329 {
00330 int retval;
00331
00332 #ifndef __s390x__
00333 __asm__ __volatile__(
00334 " bcr 15,0\n"
00335 " lr %0,%3\n"
00336 " cs %0,%4,0(%2)\n"
00337 " ipm %0\n"
00338 " srl %0,28\n"
00339 "0:"
00340 : "=&d" (retval), "=m" (_q_value)
00341 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00342 "m" (_q_value) : "cc", "memory" );
00343 #else
00344 __asm__ __volatile__(
00345 " bcr 15,0\n"
00346 " lgr %0,%3\n"
00347 " csg %0,%4,0(%2)\n"
00348 " ipm %0\n"
00349 " srl %0,28\n"
00350 "0:"
00351 : "=&d" (retval), "=m" (_q_value)
00352 : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
00353 "m" (_q_value) : "cc", "memory" );
00354 #endif
00355
00356 return retval == 0;
00357 }
00358
00359 template <typename T>
00360 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
00361 {
00362 return testAndSetAcquire(expectedValue, newValue);
00363 }
00364
00365 template <typename T>
00366 Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
00367 {
00368 #ifndef __s390x__
00369 return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "");
00370 #else
00371 return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "");
00372 #endif
00373 }
00374
00375 template <typename T>
00376 Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
00377 {
00378 #ifndef __s390x__
00379 return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n");
00380 #else
00381 return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n");
00382 #endif
00383 }
00384
00385 template <typename T>
00386 Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
00387 {
00388 #ifndef __s390x__
00389 return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", "");
00390 #else
00391 return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", "");
00392 #endif
00393 }
00394
00395 template <typename T>
00396 Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
00397 {
00398 return fetchAndStoreAcquire(newValue);
00399 }
00400
00401
00402 template <typename T>
00403 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
00404 {
00405 return fetchAndAddOrdered(valueToAdd);
00406 }
00407
00408 template <typename T>
00409 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
00410 {
00411 return fetchAndAddOrdered(valueToAdd);
00412 }
00413
00414 template <typename T>
00415 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
00416 {
00417 return fetchAndAddOrdered(valueToAdd);
00418 }
00419
00420 #undef __GNU_EXTENSION
00421
00422 QT_END_NAMESPACE
00423
00424 QT_END_HEADER
00425
00426 #endif // QATOMIC_S390_H