- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qatomic_alpha.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtCore module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    00039 **
    00040 ****************************************************************************/
    00041
    00042 #ifndef QATOMIC_ALPHA_H
    00043 #define QATOMIC_ALPHA_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 #if defined(Q_CC_GNU)
    00105
    00106 inline bool QBasicAtomicInt::ref()
    00107 {
    00108     register int old, tmp;
    00109     asm volatile("1:\n"
    00110                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00111                  "addl  %0,1,%1\n" /* tmp=old+1;                              */
    00112                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00113                  "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
    00114                  "br    3f\n"      /* goto 3;                                 */
    00115                  "2: br 1b\n"      /* goto 1;                                 */
    00116                  "3:\n"
    00117                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00118                  :
    00119                  : "memory");
    00120     return old != -1;
    00121 }
    00122
    00123 inline bool QBasicAtomicInt::deref()
    00124 {
    00125     register int old, tmp;
    00126     asm volatile("1:\n"
    00127                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00128                  "subl  %0,1,%1\n" /* tmp=old-1;                              */
    00129                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00130                  "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
    00131                  "br    3f\n"      /* goto 3;                                 */
    00132                  "2: br 1b\n"      /* goto 1;                                 */
    00133                  "3:\n"
    00134                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00135                  :
    00136                  : "memory");
    00137     return old != 1;
    00138 }
    00139
    00140 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
    00141 {
    00142     register int ret;
    00143     asm volatile("1:\n"
    00144                  "ldl_l %0,%1\n"   /* ret=*ptr;                               */
    00145                  "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1;   */
    00146                  "beq   %0,3f\n"   /* if (ret==0) goto 3;                     */
    00147                  "mov   %3,%0\n"   /* ret=newval;                             */
    00148                  "stl_c %0,%1\n"   /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
    00149                  "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
    00150                  "br    3f\n"      /* goto 3;                                 */
    00151                  "2: br 1b\n"      /* goto 1;                                 */
    00152                  "3:\n"
    00153                  : "=&r" (ret), "+m" (_q_value)
    00154                  : "r" (expectedValue), "r" (newValue)
    00155                  : "memory");
    00156     return ret != 0;
    00157 }
    00158
    00159 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
    00160 {
    00161     register int ret;
    00162     asm volatile("1:\n"
    00163                  "ldl_l %0,%1\n"   /* ret=*ptr;                               */
    00164                  "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1;   */
    00165                  "beq   %0,3f\n"   /* if (ret==0) goto 3;                     */
    00166                  "mov   %3,%0\n"   /* ret=newval;                             */
    00167                  "stl_c %0,%1\n"   /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
    00168                  "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
    00169                  "br    3f\n"      /* goto 3;                                 */
    00170                  "2: br 1b\n"      /* goto 1;                                 */
    00171                  "3:\n"
    00172                  "mb\n"
    00173                  : "=&r" (ret), "+m" (_q_value)
    00174                  : "r" (expectedValue), "r" (newValue)
    00175                  : "memory");
    00176     return ret != 0;
    00177 }
    00178
    00179 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
    00180 {
    00181     register int ret;
    00182     asm volatile("mb\n"
    00183                  "1:\n"
    00184                  "ldl_l %0,%1\n"   /* ret=*ptr;                               */
    00185                  "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1;   */
    00186                  "beq   %0,3f\n"   /* if (ret==0) goto 3;                     */
    00187                  "mov   %3,%0\n"   /* ret=newval;                             */
    00188                  "stl_c %0,%1\n"   /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
    00189                  "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
    00190                  "br    3f\n"      /* goto 3;                                 */
    00191                  "2: br 1b\n"      /* goto 1;                                 */
    00192                  "3:\n"
    00193                  : "=&r" (ret), "+m" (_q_value)
    00194                  : "r" (expectedValue), "r" (newValue)
    00195                  : "memory");
    00196     return ret != 0;
    00197 }
    00198
    00199 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
    00200 {
    00201     register int old, tmp;
    00202     asm volatile("1:\n"
    00203                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00204                  "mov   %3,%1\n"   /* tmp=newval;                             */
    00205                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00206                  "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
    00207                  "br    3f\n"      /* goto 3;                                 */
    00208                  "2: br 1b\n"      /* goto 1;                                 */
    00209                  "3:\n"
    00210                  : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
    00211                  : "r" (newValue)
    00212                  : "memory");
    00213     return old;
    00214 }
    00215
    00216 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
    00217 {
    00218     register int old, tmp;
    00219     asm volatile("1:\n"
    00220                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00221                  "mov   %3,%1\n"   /* tmp=newval;                             */
    00222                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00223                  "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
    00224                  "br    3f\n"      /* goto 3;                                 */
    00225                  "2: br 1b\n"      /* goto 1;                                 */
    00226                  "3:\n"
    00227                  "mb\n"
    00228                  : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
    00229                  : "r" (newValue)
    00230                  : "memory");
    00231     return old;
    00232 }
    00233
    00234 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
    00235 {
    00236     register int old, tmp;
    00237     asm volatile("mb\n"
    00238                  "1:\n"
    00239                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00240                  "mov   %3,%1\n"   /* tmp=newval;                             */
    00241                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00242                  "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
    00243                  "br    3f\n"      /* goto 3;                                 */
    00244                  "2: br 1b\n"      /* goto 1;                                 */
    00245                  "3:\n"
    00246                  : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
    00247                  : "r" (newValue)
    00248                  : "memory");
    00249     return old;
    00250 }
    00251
    00252 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
    00253 {
    00254     register int old, tmp;
    00255     asm volatile("1:\n"
    00256                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00257                  "addl  %0,%3,%1\n"/* tmp=old+value;                          */
    00258                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00259                  "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
    00260                  "br    3f\n"      /* goto 3;                                 */
    00261                  "2: br 1b\n"      /* goto 1;                                 */
    00262                  "3:\n"
    00263                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00264                  : "r" (valueToAdd)
    00265                  : "memory");
    00266     return old;
    00267 }
    00268
    00269 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
    00270 {
    00271     register int old, tmp;
    00272     asm volatile("1:\n"
    00273                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00274                  "addl  %0,%3,%1\n"/* tmp=old+value;                          */
    00275                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00276                  "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
    00277                  "br    3f\n"      /* goto 3;                                 */
    00278                  "2: br 1b\n"      /* goto 1;                                 */
    00279                  "3:\n"
    00280                  "mb\n"
    00281                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00282                  : "r" (valueToAdd)
    00283                  : "memory");
    00284     return old;
    00285 }
    00286
    00287 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
    00288 {
    00289     register int old, tmp;
    00290     asm volatile("mb\n"
    00291                  "1:\n"
    00292                  "ldl_l %0,%2\n"   /* old=*ptr;                               */
    00293                  "addl  %0,%3,%1\n"/* tmp=old+value;                          */
    00294                  "stl_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00295                  "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
    00296                  "br    3f\n"      /* goto 3;                                 */
    00297                  "2: br 1b\n"      /* goto 1;                                 */
    00298                  "3:\n"
    00299                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00300                  : "r" (valueToAdd)
    00301                  : "memory");
    00302     return old;
    00303 }
    00304
    00305 template <typename T>
    00306 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
    00307 {
    00308     register void *ret;
    00309     asm volatile("1:\n"
    00310                  "ldq_l %0,%1\n"   /* ret=*ptr;                               */
    00311                  "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1;   */
    00312                  "beq   %0,3f\n"   /* if (tmp==0) goto 3;                     */
    00313                  "mov   %3,%0\n"   /* tmp=newval;                             */
    00314                  "stq_c %0,%1\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00315                  "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
    00316                  "br    3f\n"      /* goto 3;                                 */
    00317                  "2: br 1b\n"      /* goto 1;                                 */
    00318                  "3:\n"
    00319                  : "=&r" (ret), "+m" (_q_value)
    00320                  : "r" (expectedValue), "r" (newValue)
    00321                  : "memory");
    00322     return ret != 0;
    00323 }
    00324
    00325 template <typename T>
    00326 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
    00327 {
    00328     register void *ret;
    00329     asm volatile("1:\n"
    00330                  "ldq_l %0,%1\n"   /* ret=*ptr;                               */
    00331                  "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1;   */
    00332                  "beq   %0,3f\n"   /* if (tmp==0) goto 3;                     */
    00333                  "mov   %3,%0\n"   /* tmp=newval;                             */
    00334                  "stq_c %0,%1\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00335                  "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
    00336                  "br    3f\n"      /* goto 3;                                 */
    00337                  "2: br 1b\n"      /* goto 1;                                 */
    00338                  "3:\n"
    00339                  "mb\n"
    00340                  : "=&r" (ret), "+m" (_q_value)
    00341                  : "r" (expectedValue), "r" (newValue)
    00342                  : "memory");
    00343     return ret != 0;
    00344 }
    00345
    00346 template <typename T>
    00347 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
    00348 {
    00349     register void *ret;
    00350     asm volatile("mb\n"
    00351                  "1:\n"
    00352                  "ldq_l %0,%1\n"   /* ret=*ptr;                               */
    00353                  "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1;   */
    00354                  "beq   %0,3f\n"   /* if (tmp==0) goto 3;                     */
    00355                  "mov   %3,%0\n"   /* tmp=newval;                             */
    00356                  "stq_c %0,%1\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00357                  "beq   %0,2f\n"   /* if (ret==0) goto 2;                     */
    00358                  "br    3f\n"      /* goto 3;                                 */
    00359                  "2: br 1b\n"      /* goto 1;                                 */
    00360                  "3:\n"
    00361                  : "=&r" (ret), "+m" (_q_value)
    00362                  : "r" (expectedValue), "r" (newValue)
    00363                  : "memory");
    00364     return ret != 0;
    00365 }
    00366
    00367 template <typename T>
    00368 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
    00369 {
    00370     register T *old, *tmp;
    00371     asm volatile("1:\n"
    00372                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
    00373                  "mov   %3,%1\n"   /* tmp=newval;                             */
    00374                  "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00375                  "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
    00376                  "br    3f\n"      /* goto 3;                                 */
    00377                  "2: br 1b\n"      /* goto 1;                                 */
    00378                  "3:\n"
    00379                  : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
    00380                  : "r" (newValue)
    00381                  : "memory");
    00382     return old;
    00383 }
    00384
    00385 template <typename T>
    00386 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
    00387 {
    00388     register T *old, *tmp;
    00389     asm volatile("1:\n"
    00390                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
    00391                  "mov   %3,%1\n"   /* tmp=newval;                             */
    00392                  "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00393                  "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
    00394                  "br    3f\n"      /* goto 3;                                 */
    00395                  "2: br 1b\n"      /* goto 1;                                 */
    00396                  "3:\n"
    00397                  "mb\n"
    00398                  : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
    00399                  : "r" (newValue)
    00400                  : "memory");
    00401     return old;
    00402 }
    00403
    00404 template <typename T>
    00405 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
    00406 {
    00407     register T *old, *tmp;
    00408     asm volatile("mb\n"
    00409                  "1:\n"
    00410                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
    00411                  "mov   %3,%1\n"   /* tmp=newval;                             */
    00412                  "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00413                  "beq   %1,2f\n"   /* if (tmp==0) goto 2;                     */
    00414                  "br    3f\n"      /* goto 3;                                 */
    00415                  "2: br 1b\n"      /* goto 1;                                 */
    00416                  "3:\n"
    00417                  : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
    00418                  : "r" (newValue)
    00419                  : "memory");
    00420     return old;
    00421 }
    00422
    00423 template <typename T>
    00424 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
    00425 {
    00426     register T *old, *tmp;
    00427     asm volatile("1:\n"
    00428                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
    00429                  "addq  %0,%3,%1\n"/* tmp=old+value;                          */
    00430                  "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00431                  "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
    00432                  "br    3f\n"      /* goto 3;                                 */
    00433                  "2: br 1b\n"      /* goto 1;                                 */
    00434                  "3:\n"
    00435                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00436                  : "r" (valueToAdd)
    00437                  : "memory");
    00438     return reinterpret_cast<T *>(old);
    00439 }
    00440
    00441 template <typename T>
    00442 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
    00443 {
    00444     register T *old, *tmp;
    00445     asm volatile("1:\n"
    00446                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
    00447                  "addq  %0,%3,%1\n"/* tmp=old+value;                          */
    00448                  "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00449                  "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
    00450                  "br    3f\n"      /* goto 3;                                 */
    00451                  "2: br 1b\n"      /* goto 1;                                 */
    00452                  "3:\n"
    00453                  "mb\n"
    00454                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00455                  : "r" (valueToAdd)
    00456                  : "memory");
    00457     return reinterpret_cast<T *>(old);
    00458 }
    00459
    00460 template <typename T>
    00461 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
    00462 {
    00463     register T *old, *tmp;
    00464     asm volatile("mb\n"
    00465                  "1:\n"
    00466                  "ldq_l %0,%2\n"   /* old=*ptr;                               */
    00467                  "addq  %0,%3,%1\n"/* tmp=old+value;                          */
    00468                  "stq_c %1,%2\n"   /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
    00469                  "beq   %1,2f\n"   /* if (tmp == 0) goto 2;                   */
    00470                  "br    3f\n"      /* goto 3;                                 */
    00471                  "2: br 1b\n"      /* goto 1;                                 */
    00472                  "3:\n"
    00473                  : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
    00474                  : "r" (valueToAdd)
    00475                  : "memory");
    00476     return reinterpret_cast<T *>(old);
    00477 }
    00478
    00479 #else // !Q_CC_GNU
    00480
    00481 extern "C" {
    00482     Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
    00483     Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval);
    00484     Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval);
    00485     Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
    00486     Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
    00487     Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
    00488     Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
    00489     Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
    00490     Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
    00491     Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
    00492     Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value);
    00493 } // extern "C"
    00494
    00495 inline bool QBasicAtomicInt::ref()
    00496 {
    00497     return q_atomic_increment(&_q_value) != 0;
    00498 }
    00499
    00500 inline bool QBasicAtomicInt::deref()
    00501 {
    00502     return q_atomic_decrement(&_q_value) != 0;
    00503 }
    00504
    00505 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
    00506 {
    00507     return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
    00508 }
    00509
    00510 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
    00511 {
    00512     return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
    00513 }
    00514
    00515 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
    00516 {
    00517     return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
    00518 }
    00519
    00520 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
    00521 {
    00522     return q_atomic_set_int(&_q_value, newValue);
    00523 }
    00524
    00525 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
    00526 {
    00527     return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
    00528 }
    00529
    00530 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
    00531 {
    00532     return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
    00533 }
    00534
    00535 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
    00536 {
    00537     return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
    00538 }
    00539
    00540 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
    00541 {
    00542     return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd);
    00543 }
    00544
    00545 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
    00546 {
    00547     return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd);
    00548 }
    00549
    00550 template <typename T>
    00551 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
    00552 {
    00553     return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
    00554 }
    00555
    00556 template <typename T>
    00557 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
    00558 {
    00559     return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
    00560 }
    00561
    00562 template <typename T>
    00563 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
    00564 {
    00565     return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
    00566 }
    00567
    00568 template <typename T>
    00569 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
    00570 {
    00571     return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
    00572 }
    00573
    00574 template <typename T>
    00575 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
    00576 {
    00577     return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
    00578 }
    00579
    00580 template <typename T>
    00581 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
    00582 {
    00583     return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
    00584 }
    00585
    00586 template <typename T>
    00587 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
    00588 {
    00589     return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, newValue));
    00590 }
    00591 template <typename T>
    00592 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
    00593 {
    00594     return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, newValue));
    00595 }
    00596
    00597 template <typename T>
    00598 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
    00599 {
    00600     return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, newValue));
    00601 }
    00602
    00603 #endif // Q_CC_GNU
    00604
    00605 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
    00606 {
    00607     return testAndSetAcquire(expectedValue, newValue);
    00608 }
    00609
    00610 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
    00611 {
    00612     return fetchAndStoreAcquire(newValue);
    00613 }
    00614
    00615 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
    00616 {
    00617     return fetchAndAddAcquire(valueToAdd);
    00618 }
    00619
    00620 template <typename T>
    00621 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
    00622 {
    00623     return testAndSetAcquire(expectedValue, newValue);
    00624 }
    00625
    00626 template <typename T>
    00627 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
    00628 {
    00629     return fetchAndStoreAcquire(newValue);
    00630 }
    00631
    00632 template <typename T>
    00633 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
    00634 {
    00635     return fetchAndAddAcquire(valueToAdd);
    00636 }
    00637
    00638 QT_END_NAMESPACE
    00639
    00640 QT_END_HEADER
    00641
    00642 #endif // QATOMIC_ALPHA_H