diff options
-rw-r--r-- | src/corelib/arch/arch.pri | 3 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_gcc.h | 129 | ||||
-rw-r--r-- | src/corelib/thread/qbasicatomic.h | 2 |
3 files changed, 133 insertions, 1 deletions
diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index e8699a27c6..ba6fc71e2f 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -30,7 +30,8 @@ integrity:HEADERS += arch/qatomic_integrity.h arch/qatomic_x86_64.h \ arch/qatomic_sh.h \ arch/qatomic_sh4a.h \ - arch/qatomic_nacl.h + arch/qatomic_nacl.h \ + arch/qatomic_gcc.h QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH DEPENDPATH += $$QT_ARCH_CPP diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h new file mode 100644 index 0000000000..2788aaf59b --- /dev/null +++ b/src/corelib/arch/qatomic_gcc.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QATOMIC_GCC_H +#define QATOMIC_GCC_H + +#include <QtCore/qgenericatomic.h> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +#if 0 +#pragma qt_sync_stop_processing +#endif + +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; + +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +#define Q_ATOMIC_INT32_IS_SUPPORTED +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +#define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> > +{ + // The GCC intrinsics all have fully-ordered memory semantics, so we define + // only the xxxRelaxed functions. The exception is __sync_lock_and_test, + // which has acquire semantics, so we need to define the Release and + // Ordered versions too. + + typedef T Type; + +#ifndef __ia64__ + static T loadAcquire(T &_q_value) + { + T tmp = _q_value; + __sync_synchronize(); + return tmp; + } + + static void storeRelease(T &_q_value, T newValue) + { + __sync_synchronize(); + _q_value = newValue; + } +#endif + + static bool isTestAndSetNative() { return false; } + static bool isTestAndSetWaitFree() { return false; } + static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) + { + return __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue); + } + + static T fetchAndStoreRelaxed(T &_q_value, T newValue) + { + return __sync_lock_test_and_set(&_q_value, newValue); + } + + static T fetchAndStoreRelease(T &_q_value, T newValue) + { + __sync_synchronize(); + return __sync_lock_test_and_set(&_q_value, newValue); + } + + static T fetchAndStoreOrdered(T &_q_value, T newValue) + { + return fetchAndStoreRelease(_q_value, newValue); + } + + static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) + { + return __sync_fetch_and_add(&_q_value, valueToAdd * QAtomicAdditiveType<T>::AddScale); + } +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QATOMIC_GCC_H diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index a9a3fe92c6..18febd36de 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -58,6 +58,8 @@ # include "QtCore/qatomic_mips.h" #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) # include <QtCore/qatomic_x86_64.h> +#elif defined(Q_CC_GNU) +# include <QtCore/qatomic_gcc.h> #else # define QT_OLD_ATOMICS #endif |