LCOV - code coverage report
Current view: top level - usr/include/x86_64-linux-gnu/qt5/QtCore - qgenericatomic.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 1 100.0 %
Date: 2016-11-29 15:07:43 Functions: 0 0 -

          Line data    Source code
       1             : /****************************************************************************
       2             : **
       3             : ** Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
       4             : ** Contact: http://www.qt-project.org/legal
       5             : **
       6             : ** This file is part of the QtCore module of the Qt Toolkit.
       7             : **
       8             : ** $QT_BEGIN_LICENSE:LGPL$
       9             : ** Commercial License Usage
      10             : ** Licensees holding valid commercial Qt licenses may use this file in
      11             : ** accordance with the commercial license agreement provided with the
      12             : ** Software or, alternatively, in accordance with the terms contained in
      13             : ** a written agreement between you and Digia.  For licensing terms and
      14             : ** conditions see http://qt.digia.com/licensing.  For further information
      15             : ** use the contact form at http://qt.digia.com/contact-us.
      16             : **
      17             : ** GNU Lesser General Public License Usage
      18             : ** Alternatively, this file may be used under the terms of the GNU Lesser
      19             : ** General Public License version 2.1 as published by the Free Software
      20             : ** Foundation and appearing in the file LICENSE.LGPL included in the
      21             : ** packaging of this file.  Please review the following information to
      22             : ** ensure the GNU Lesser General Public License version 2.1 requirements
      23             : ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
      24             : **
      25             : ** In addition, as a special exception, Digia gives you certain additional
      26             : ** rights.  These rights are described in the Digia Qt LGPL Exception
      27             : ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
      28             : **
      29             : ** GNU General Public License Usage
      30             : ** Alternatively, this file may be used under the terms of the GNU
      31             : ** General Public License version 3.0 as published by the Free Software
      32             : ** Foundation and appearing in the file LICENSE.GPL included in the
      33             : ** packaging of this file.  Please review the following information to
      34             : ** ensure the GNU General Public License version 3.0 requirements will be
      35             : ** met: http://www.gnu.org/copyleft/gpl.html.
      36             : **
      37             : **
      38             : ** $QT_END_LICENSE$
      39             : **
      40             : ****************************************************************************/
      41             : 
      42             : #ifndef QGENERICATOMIC_H
      43             : #define QGENERICATOMIC_H
      44             : 
      45             : #include <QtCore/qglobal.h>
      46             : #include <QtCore/qtypeinfo.h>
      47             : 
      48             : QT_BEGIN_NAMESPACE
      49             : 
      50             : #if 0
      51             : // silence syncqt warnings
      52             : QT_END_NAMESPACE
      53             : #pragma qt_sync_skip_header_check
      54             : #pragma qt_sync_stop_processing
      55             : #endif
      56             : 
      57             : #ifdef Q_CC_GNU
      58             : // lowercase is fine, we'll undef it below
      59             : #define always_inline __attribute__((always_inline, gnu_inline))
      60             : #else
      61             : #define always_inline
      62             : #endif
      63             : 
      64             : template<int> struct QAtomicOpsSupport { enum { IsSupported = 0 }; };
      65             : template<> struct QAtomicOpsSupport<4> { enum { IsSupported = 1 }; };
      66             : 
      67             : template <typename T> struct QAtomicAdditiveType
      68             : {
      69             :     typedef T AdditiveT;
      70             :     static const int AddScale = 1;
      71             : };
      72             : template <typename T> struct QAtomicAdditiveType<T *>
      73             : {
      74             :     typedef qptrdiff AdditiveT;
      75             :     static const int AddScale = sizeof(T);
      76             : };
      77             : 
      78             : // not really atomic...
      79             : template <typename BaseClass> struct QGenericAtomicOps
      80             : {
      81             :     template <typename T> struct AtomicType { typedef T Type; typedef T *PointerType; };
      82             : 
      83             :     template <typename T> static void acquireMemoryFence(const T &_q_value) Q_DECL_NOTHROW
      84             :     {
      85             :         BaseClass::orderedMemoryFence(_q_value);
      86             :     }
      87             :     template <typename T> static void releaseMemoryFence(const T &_q_value) Q_DECL_NOTHROW
      88             :     {
      89             :         BaseClass::orderedMemoryFence(_q_value);
      90             :     }
      91             :     template <typename T> static void orderedMemoryFence(const T &) Q_DECL_NOTHROW
      92             :     {
      93             :     }
      94             : 
      95             :     template <typename T> static inline always_inline
      96             :     T load(const T &_q_value) Q_DECL_NOTHROW
      97             :     {
      98        1170 :         return _q_value;
      99             :     }
     100             : 
     101             :     template <typename T, typename X> static inline always_inline
     102             :     void store(T &_q_value, X newValue) Q_DECL_NOTHROW
     103             :     {
     104             :         _q_value = newValue;
     105             :     }
     106             : 
     107             :     template <typename T> static inline always_inline
     108             :     T loadAcquire(const T &_q_value) Q_DECL_NOTHROW
     109             :     {
     110             :         T tmp = *static_cast<const volatile T *>(&_q_value);
     111             :         BaseClass::acquireMemoryFence(_q_value);
     112             :         return tmp;
     113             :     }
     114             : 
     115             :     template <typename T, typename X> static inline always_inline
     116             :     void storeRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
     117             :     {
     118             :         BaseClass::releaseMemoryFence(_q_value);
     119             :         *static_cast<volatile T *>(&_q_value) = newValue;
     120             :     }
     121             : 
     122             :     static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW
     123             :     { return BaseClass::isFetchAndAddNative(); }
     124             :     static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW
     125             :     { return BaseClass::isFetchAndAddWaitFree(); }
     126             :     template <typename T> static inline always_inline
     127             :     bool ref(T &_q_value) Q_DECL_NOTHROW
     128             :     {
     129             :         return BaseClass::fetchAndAddRelaxed(_q_value, 1) != T(-1);
     130             :     }
     131             : 
     132             :     template <typename T> static inline always_inline
     133             :     bool deref(T &_q_value) Q_DECL_NOTHROW
     134             :     {
     135             :          return BaseClass::fetchAndAddRelaxed(_q_value, -1) != 1;
     136             :     }
     137             : 
     138             : #if 0
     139             :     // These functions have no default implementation
     140             :     // Archictectures must implement them
     141             :     static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW;
     142             :     static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW;
     143             :     template <typename T, typename X> static inline
     144             :     bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW;
     145             :     template <typename T, typename X> static inline
     146             :     bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW;
     147             : #endif
     148             : 
     149             :     template <typename T, typename X> static inline always_inline
     150             :     bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
     151             :     {
     152             :         bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
     153             :         BaseClass::acquireMemoryFence(_q_value);
     154             :         return tmp;
     155             :     }
     156             : 
     157             :     template <typename T, typename X> static inline always_inline
     158             :     bool testAndSetRelease(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
     159             :     {
     160             :         BaseClass::releaseMemoryFence(_q_value);
     161             :         return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
     162             :     }
     163             : 
     164             :     template <typename T, typename X> static inline always_inline
     165             :     bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
     166             :     {
     167             :         BaseClass::orderedMemoryFence(_q_value);
     168             :         return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
     169             :     }
     170             : 
     171             :     template <typename T, typename X> static inline always_inline
     172             :     bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
     173             :     {
     174             :         bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
     175             :         BaseClass::acquireMemoryFence(_q_value);
     176             :         return tmp;
     177             :     }
     178             : 
     179             :     template <typename T, typename X> static inline always_inline
     180             :     bool testAndSetRelease(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
     181             :     {
     182             :         BaseClass::releaseMemoryFence(_q_value);
     183             :         return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
     184             :     }
     185             : 
     186             :     template <typename T, typename X> static inline always_inline
     187             :     bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
     188             :     {
     189             :         BaseClass::orderedMemoryFence(_q_value);
     190             :         return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
     191             :     }
     192             : 
     193             :     static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
     194             :     static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
     195             : 
     196             :     template <typename T, typename X> static inline always_inline
     197             :     T fetchAndStoreRelaxed(T &_q_value, X newValue) Q_DECL_NOTHROW
     198             :     {
     199             :         // implement fetchAndStore on top of testAndSet
     200             :         Q_FOREVER {
     201             :             T tmp = load(_q_value);
     202             :             if (BaseClass::testAndSetRelaxed(_q_value, tmp, newValue))
     203             :                 return tmp;
     204             :         }
     205             :     }
     206             : 
     207             :     template <typename T, typename X> static inline always_inline
     208             :     T fetchAndStoreAcquire(T &_q_value, X newValue) Q_DECL_NOTHROW
     209             :     {
     210             :         T tmp = BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
     211             :         BaseClass::acquireMemoryFence(_q_value);
     212             :         return tmp;
     213             :     }
     214             : 
     215             :     template <typename T, typename X> static inline always_inline
     216             :     T fetchAndStoreRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
     217             :     {
     218             :         BaseClass::releaseMemoryFence(_q_value);
     219             :         return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
     220             :     }
     221             : 
     222             :     template <typename T, typename X> static inline always_inline
     223             :     T fetchAndStoreOrdered(T &_q_value, X newValue) Q_DECL_NOTHROW
     224             :     {
     225             :         BaseClass::orderedMemoryFence(_q_value);
     226             :         return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
     227             :     }
     228             : 
     229             :     static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return false; }
     230             :     static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
     231             :     template <typename T> static inline always_inline
     232             :     T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     233             :     {
     234             :         // implement fetchAndAdd on top of testAndSet
     235             :         Q_FOREVER {
     236             :             T tmp = BaseClass::load(_q_value);
     237             :             if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp + valueToAdd)))
     238             :                 return tmp;
     239             :         }
     240             :     }
     241             : 
     242             :     template <typename T> static inline always_inline
     243             :     T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     244             :     {
     245             :         T tmp = BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
     246             :         BaseClass::acquireMemoryFence(_q_value);
     247             :         return tmp;
     248             :     }
     249             : 
     250             :     template <typename T> static inline always_inline
     251             :     T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     252             :     {
     253             :         BaseClass::releaseMemoryFence(_q_value);
     254             :         return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
     255             :     }
     256             : 
     257             :     template <typename T> static inline always_inline
     258             :     T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     259             :     {
     260             :         BaseClass::orderedMemoryFence(_q_value);
     261             :         return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
     262             :     }
     263             : 
     264             :     template <typename T> static inline always_inline
     265             :     T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
     266             :     {
     267             :         // implement fetchAndSub on top of fetchAndAdd
     268             :         return fetchAndAddRelaxed(_q_value, -operand);
     269             :     }
     270             : 
     271             :     template <typename T> static inline always_inline
     272             :     T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
     273             :     {
     274             :         T tmp = BaseClass::fetchAndSubRelaxed(_q_value, operand);
     275             :         BaseClass::acquireMemoryFence(_q_value);
     276             :         return tmp;
     277             :     }
     278             : 
     279             :     template <typename T> static inline always_inline
     280             :     T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
     281             :     {
     282             :         BaseClass::releaseMemoryFence(_q_value);
     283             :         return BaseClass::fetchAndSubRelaxed(_q_value, operand);
     284             :     }
     285             : 
     286             :     template <typename T> static inline always_inline
     287             :     T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
     288             :     {
     289             :         BaseClass::orderedMemoryFence(_q_value);
     290             :         return BaseClass::fetchAndSubRelaxed(_q_value, operand);
     291             :     }
     292             : 
     293             :     template <typename T> static inline always_inline
     294             :     T fetchAndAndRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     295             :     {
     296             :         // implement fetchAndAnd on top of testAndSet
     297             :         Q_FOREVER {
     298             :             T tmp = BaseClass::load(_q_value);
     299             :             if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp & operand)))
     300             :                 return tmp;
     301             :         }
     302             :     }
     303             : 
     304             :     template <typename T> static inline always_inline
     305             :     T fetchAndAndAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     306             :     {
     307             :         T tmp = BaseClass::fetchAndAndRelaxed(_q_value, operand);
     308             :         BaseClass::acquireMemoryFence(_q_value);
     309             :         return tmp;
     310             :     }
     311             : 
     312             :     template <typename T> static inline always_inline
     313             :     T fetchAndAndRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     314             :     {
     315             :         BaseClass::releaseMemoryFence(_q_value);
     316             :         return BaseClass::fetchAndAndRelaxed(_q_value, operand);
     317             :     }
     318             : 
     319             :     template <typename T> static inline always_inline
     320             :     T fetchAndAndOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     321             :     {
     322             :         BaseClass::orderedMemoryFence(_q_value);
     323             :         return BaseClass::fetchAndAndRelaxed(_q_value, operand);
     324             :     }
     325             : 
     326             :     template <typename T> static inline always_inline
     327             :     T fetchAndOrRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     328             :     {
     329             :         // implement fetchAndOr on top of testAndSet
     330             :         Q_FOREVER {
     331             :             T tmp = BaseClass::load(_q_value);
     332             :             if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp | operand)))
     333             :                 return tmp;
     334             :         }
     335             :     }
     336             : 
     337             :     template <typename T> static inline always_inline
     338             :     T fetchAndOrAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     339             :     {
     340             :         T tmp = BaseClass::fetchAndOrRelaxed(_q_value, operand);
     341             :         BaseClass::acquireMemoryFence(_q_value);
     342             :         return tmp;
     343             :     }
     344             : 
     345             :     template <typename T> static inline always_inline
     346             :     T fetchAndOrRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     347             :     {
     348             :         BaseClass::releaseMemoryFence(_q_value);
     349             :         return BaseClass::fetchAndOrRelaxed(_q_value, operand);
     350             :     }
     351             : 
     352             :     template <typename T> static inline always_inline
     353             :     T fetchAndOrOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     354             :     {
     355             :         BaseClass::orderedMemoryFence(_q_value);
     356             :         return BaseClass::fetchAndOrRelaxed(_q_value, operand);
     357             :     }
     358             : 
     359             :     template <typename T> static inline always_inline
     360             :     T fetchAndXorRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     361             :     {
     362             :         // implement fetchAndXor on top of testAndSet
     363             :         Q_FOREVER {
     364             :             T tmp = BaseClass::load(_q_value);
     365             :             if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp ^ operand)))
     366             :                 return tmp;
     367             :         }
     368             :     }
     369             : 
     370             :     template <typename T> static inline always_inline
     371             :     T fetchAndXorAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     372             :     {
     373             :         T tmp = BaseClass::fetchAndXorRelaxed(_q_value, operand);
     374             :         BaseClass::acquireMemoryFence(_q_value);
     375             :         return tmp;
     376             :     }
     377             : 
     378             :     template <typename T> static inline always_inline
     379             :     T fetchAndXorRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     380             :     {
     381             :         BaseClass::releaseMemoryFence(_q_value);
     382             :         return BaseClass::fetchAndXorRelaxed(_q_value, operand);
     383             :     }
     384             : 
     385             :     template <typename T> static inline always_inline
     386             :     T fetchAndXorOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
     387             :     {
     388             :         BaseClass::orderedMemoryFence(_q_value);
     389             :         return BaseClass::fetchAndXorRelaxed(_q_value, operand);
     390             :     }
     391             : };
     392             : 
     393             : #undef always_inline
     394             : 
     395             : QT_END_NAMESPACE
     396             : #endif // QGENERICATOMIC_H

Generated by: LCOV version 1.11