qbasicatomic.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 QBASICATOMIC_H
00043 #define QBASICATOMIC_H
00044 
00045 #include <QtCore/qglobal.h>
00046 
00047 QT_BEGIN_HEADER
00048 
00049 QT_BEGIN_NAMESPACE
00050 
00051 QT_MODULE(Core)
00052 
00053 class Q_CORE_EXPORT QBasicAtomicInt
00054 {
00055 public:
00056 #ifdef QT_ARCH_PARISC
00057     int _q_lock[4];
00058 #endif
00059 #if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE)
00060     union { // needed for Q_BASIC_ATOMIC_INITIALIZER
00061         volatile long _q_value;
00062     };
00063 #else
00064     volatile int _q_value;
00065 #endif
00066 
00067     // Non-atomic API
00068     inline bool operator==(int value) const
00069     {
00070         return _q_value == value;
00071     }
00072 
00073     inline bool operator!=(int value) const
00074     {
00075         return _q_value != value;
00076     }
00077 
00078     inline bool operator!() const
00079     {
00080         return _q_value == 0;
00081     }
00082 
00083     inline operator int() const
00084     {
00085         return _q_value;
00086     }
00087 
00088     inline QBasicAtomicInt &operator=(int value)
00089     {
00090 #ifdef QT_ARCH_PARISC
00091         this->_q_lock[0] = this->_q_lock[1] = this->_q_lock[2] = this->_q_lock[3] = -1;
00092 #endif
00093         _q_value = value;
00094         return *this;
00095     }
00096 
00097     // Atomic API, implemented in qatomic_XXX.h
00098 
00099     static bool isReferenceCountingNative();
00100     static bool isReferenceCountingWaitFree();
00101 
00102     bool ref();
00103     bool deref();
00104 
00105     static bool isTestAndSetNative();
00106     static bool isTestAndSetWaitFree();
00107 
00108     bool testAndSetRelaxed(int expectedValue, int newValue);
00109     bool testAndSetAcquire(int expectedValue, int newValue);
00110     bool testAndSetRelease(int expectedValue, int newValue);
00111     bool testAndSetOrdered(int expectedValue, int newValue);
00112 
00113     static bool isFetchAndStoreNative();
00114     static bool isFetchAndStoreWaitFree();
00115 
00116     int fetchAndStoreRelaxed(int newValue);
00117     int fetchAndStoreAcquire(int newValue);
00118     int fetchAndStoreRelease(int newValue);
00119     int fetchAndStoreOrdered(int newValue);
00120 
00121     static bool isFetchAndAddNative();
00122     static bool isFetchAndAddWaitFree();
00123 
00124     int fetchAndAddRelaxed(int valueToAdd);
00125     int fetchAndAddAcquire(int valueToAdd);
00126     int fetchAndAddRelease(int valueToAdd);
00127     int fetchAndAddOrdered(int valueToAdd);
00128 };
00129 
00130 template <typename T>
00131 class QBasicAtomicPointer
00132 {
00133 public:
00134 #ifdef QT_ARCH_PARISC
00135     int _q_lock[4];
00136 #endif
00137 #if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE)
00138     union {
00139         T * volatile _q_value;
00140 #  if !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86)
00141         qint64
00142 #  else
00143         long
00144 #  endif
00145         volatile _q_value_integral;
00146     };
00147 #else
00148     T * volatile _q_value;
00149 #endif
00150 
00151     // Non-atomic API
00152     inline bool operator==(T *value) const
00153     {
00154         return _q_value == value;
00155     }
00156 
00157     inline bool operator!=(T *value) const
00158     {
00159         return !operator==(value);
00160     }
00161 
00162     inline bool operator!() const
00163     {
00164         return operator==(0);
00165     }
00166 
00167     inline operator T *() const
00168     {
00169         return _q_value;
00170     }
00171 
00172     inline T *operator->() const
00173     {
00174         return _q_value;
00175     }
00176 
00177     inline QBasicAtomicPointer<T> &operator=(T *value)
00178     {
00179 #ifdef QT_ARCH_PARISC
00180         this->_q_lock[0] = this->_q_lock[1] = this->_q_lock[2] = this->_q_lock[3] = -1;
00181 #endif
00182         _q_value = value;
00183         return *this;
00184     }
00185 
00186     // Atomic API, implemented in qatomic_XXX.h
00187 
00188     static bool isTestAndSetNative();
00189     static bool isTestAndSetWaitFree();
00190 
00191     bool testAndSetRelaxed(T *expectedValue, T *newValue);
00192     bool testAndSetAcquire(T *expectedValue, T *newValue);
00193     bool testAndSetRelease(T *expectedValue, T *newValue);
00194     bool testAndSetOrdered(T *expectedValue, T *newValue);
00195 
00196     static bool isFetchAndStoreNative();
00197     static bool isFetchAndStoreWaitFree();
00198 
00199     T *fetchAndStoreRelaxed(T *newValue);
00200     T *fetchAndStoreAcquire(T *newValue);
00201     T *fetchAndStoreRelease(T *newValue);
00202     T *fetchAndStoreOrdered(T *newValue);
00203 
00204     static bool isFetchAndAddNative();
00205     static bool isFetchAndAddWaitFree();
00206 
00207     T *fetchAndAddRelaxed(qptrdiff valueToAdd);
00208     T *fetchAndAddAcquire(qptrdiff valueToAdd);
00209     T *fetchAndAddRelease(qptrdiff valueToAdd);
00210     T *fetchAndAddOrdered(qptrdiff valueToAdd);
00211 };
00212 
00213 #ifdef QT_ARCH_PARISC
00214 #  define Q_BASIC_ATOMIC_INITIALIZER(a) {{-1,-1,-1,-1},(a)}
00215 #elif defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE)
00216 #  define Q_BASIC_ATOMIC_INITIALIZER(a) { {(a)} }
00217 #else
00218 #  define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) }
00219 #endif
00220 
00221 QT_END_NAMESPACE
00222 QT_END_HEADER
00223 
00224 #if defined(QT_MOC) || defined(QT_BUILD_QMAKE) || defined(QT_RCC) || defined(QT_UIC) || defined(QT_BOOTSTRAPPED)
00225 #  include <QtCore/qatomic_bootstrap.h>
00226 #else
00227 #  include <QtCore/qatomic_arch.h>
00228 #endif
00229 
00230 #endif // QBASIC_ATOMIC