diff options
Diffstat (limited to 'src/corelib/arch')
-rw-r--r-- | src/corelib/arch/arch.pri | 8 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_alpha.h | 527 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_armv5.h | 10 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_armv6.h | 123 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_bfin.h | 350 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_bootstrap.h | 1 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_cxx11.h | 49 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_gcc.h | 26 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_ia64.h | 63 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_integrity.h | 295 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_mips.h | 38 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_msvc.h | 224 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_power.h | 521 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_s390.h | 433 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_sh4a.h | 540 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_sparc.h | 532 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_unix.cpp | 13 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_unix.h | 43 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_vxworks.h | 330 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_x86.h | 56 |
20 files changed, 464 insertions, 3718 deletions
diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 51e67abfd4..5c3b0b78c2 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -1,20 +1,12 @@ win32|wince:HEADERS += arch/qatomic_msvc.h -vxworks:HEADERS += arch/qatomic_vxworks.h -integrity:HEADERS += arch/qatomic_integrity.h HEADERS += \ - arch/qatomic_alpha.h \ arch/qatomic_armv5.h \ arch/qatomic_armv6.h \ arch/qatomic_armv7.h \ - arch/qatomic_bfin.h \ arch/qatomic_bootstrap.h \ arch/qatomic_ia64.h \ arch/qatomic_mips.h \ - arch/qatomic_power.h \ - arch/qatomic_s390.h \ - arch/qatomic_sh4a.h \ - arch/qatomic_sparc.h \ arch/qatomic_x86.h \ arch/qatomic_gcc.h \ arch/qatomic_cxx11.h diff --git a/src/corelib/arch/qatomic_alpha.h b/src/corelib/arch/qatomic_alpha.h deleted file mode 100644 index 5008a1acda..0000000000 --- a/src/corelib/arch/qatomic_alpha.h +++ /dev/null @@ -1,527 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_ALPHA_H -#define QATOMIC_ALPHA_H - -#include <QtCore/qoldbasicatomic.h> - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -#if defined(Q_CC_GNU) - -inline bool QBasicAtomicInt::ref() -{ - int old, tmp; - asm volatile("1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "addl %0,1,%1\n" /* tmp=old+1; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp == 0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : - : "memory"); - return old != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - int old, tmp; - asm volatile("1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "subl %0,1,%1\n" /* tmp=old-1; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : - : "memory"); - return old != 1; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - int ret; - asm volatile("1:\n" - "ldl_l %0,%1\n" /* ret=*ptr; */ - "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */ - "beq %0,3f\n" /* if (ret==0) goto 3; */ - "mov %3,%0\n" /* ret=newval; */ - "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */ - "beq %0,2f\n" /* if (ret==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret != 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - int ret; - asm volatile("1:\n" - "ldl_l %0,%1\n" /* ret=*ptr; */ - "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */ - "beq %0,3f\n" /* if (ret==0) goto 3; */ - "mov %3,%0\n" /* ret=newval; */ - "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */ - "beq %0,2f\n" /* if (ret==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - "mb\n" - : "=&r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - int ret; - asm volatile("mb\n" - "1:\n" - "ldl_l %0,%1\n" /* ret=*ptr; */ - "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */ - "beq %0,3f\n" /* if (ret==0) goto 3; */ - "mov %3,%0\n" /* ret=newval; */ - "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */ - "beq %0,2f\n" /* if (ret==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret != 0; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - int old, tmp; - asm volatile("1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "mov %3,%1\n" /* tmp=newval; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return old; -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - int old, tmp; - asm volatile("1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "mov %3,%1\n" /* tmp=newval; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - "mb\n" - : "=&r" (old), "=&r" (tmp), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return old; -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - int old, tmp; - asm volatile("mb\n" - "1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "mov %3,%1\n" /* tmp=newval; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return old; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - int old, tmp; - asm volatile("1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "addl %0,%3,%1\n"/* tmp=old+value; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp == 0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : "r" (valueToAdd) - : "memory"); - return old; -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - int old, tmp; - asm volatile("1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "addl %0,%3,%1\n"/* tmp=old+value; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp == 0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - "mb\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : "r" (valueToAdd) - : "memory"); - return old; -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - int old, tmp; - asm volatile("mb\n" - "1:\n" - "ldl_l %0,%2\n" /* old=*ptr; */ - "addl %0,%3,%1\n"/* tmp=old+value; */ - "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp == 0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : "r" (valueToAdd) - : "memory"); - return old; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - void *ret; - asm volatile("1:\n" - "ldq_l %0,%1\n" /* ret=*ptr; */ - "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */ - "beq %0,3f\n" /* if (tmp==0) goto 3; */ - "mov %3,%0\n" /* tmp=newval; */ - "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %0,2f\n" /* if (ret==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - void *ret; - asm volatile("1:\n" - "ldq_l %0,%1\n" /* ret=*ptr; */ - "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */ - "beq %0,3f\n" /* if (tmp==0) goto 3; */ - "mov %3,%0\n" /* tmp=newval; */ - "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %0,2f\n" /* if (ret==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - "mb\n" - : "=&r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - void *ret; - asm volatile("mb\n" - "1:\n" - "ldq_l %0,%1\n" /* ret=*ptr; */ - "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */ - "beq %0,3f\n" /* if (tmp==0) goto 3; */ - "mov %3,%0\n" /* tmp=newval; */ - "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %0,2f\n" /* if (ret==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - T *old, *tmp; - asm volatile("1:\n" - "ldq_l %0,%2\n" /* old=*ptr; */ - "mov %3,%1\n" /* tmp=newval; */ - "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return old; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - T *old, *tmp; - asm volatile("1:\n" - "ldq_l %0,%2\n" /* old=*ptr; */ - "mov %3,%1\n" /* tmp=newval; */ - "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - "mb\n" - : "=&r" (old), "=&r" (tmp), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return old; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - T *old, *tmp; - asm volatile("mb\n" - "1:\n" - "ldq_l %0,%2\n" /* old=*ptr; */ - "mov %3,%1\n" /* tmp=newval; */ - "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp==0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return old; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - T *old, *tmp; - asm volatile("1:\n" - "ldq_l %0,%2\n" /* old=*ptr; */ - "addq %0,%3,%1\n"/* tmp=old+value; */ - "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp == 0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : "r" (valueToAdd) - : "memory"); - return reinterpret_cast<T *>(old); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - T *old, *tmp; - asm volatile("1:\n" - "ldq_l %0,%2\n" /* old=*ptr; */ - "addq %0,%3,%1\n"/* tmp=old+value; */ - "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp == 0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - "mb\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : "r" (valueToAdd) - : "memory"); - return reinterpret_cast<T *>(old); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - T *old, *tmp; - asm volatile("mb\n" - "1:\n" - "ldq_l %0,%2\n" /* old=*ptr; */ - "addq %0,%3,%1\n"/* tmp=old+value; */ - "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */ - "beq %1,2f\n" /* if (tmp == 0) goto 2; */ - "br 3f\n" /* goto 3; */ - "2: br 1b\n" /* goto 1; */ - "3:\n" - : "=&r" (old), "=&r" (tmp), "+m"(_q_value) - : "r" (valueToAdd) - : "memory"); - return reinterpret_cast<T *>(old); -} - -#else -# error "This compiler for Alpha is not supported" -#endif // Q_CC_GNU - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -QT_END_NAMESPACE - -#endif // QATOMIC_ALPHA_H diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h index b583ec662c..6939650c54 100644 --- a/src/corelib/arch/qatomic_armv5.h +++ b/src/corelib/arch/qatomic_armv5.h @@ -72,9 +72,6 @@ QT_END_NAMESPACE # error "Qt is misconfigured: this ARMv5 implementation is only possible on Linux" #endif -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; - template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > { // kernel places a restartable cmpxchg implementation at a fixed address @@ -136,13 +133,16 @@ bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW } template<> template <typename T> inline -bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T originalValue; do { originalValue = _q_value; - if (originalValue != expectedValue) + if (originalValue != expectedValue) { + if (currentValue) + *currentValue = originalValue; return false; + } } while (_q_cmpxchg(expectedValue, newValue, &_q_value) != 0); return true; } diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 08b2b02133..4f1c758ded 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -69,16 +69,6 @@ QT_END_NAMESPACE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -#if defined(Q_COMPILER_UNICODE_STRINGS) && !defined(Q_PROCESSOR_ARM_V6) -// for ARMv5, ensure that char32_t (an uint_least32_t), is 32-bit -// it's extremely unlikely it won't be on a 32-bit ARM, but just to be sure -// For ARMv6 and up, we're sure it works, but the definition is below -template<> struct QAtomicIntegerTraits<char32_t> -{ enum { IsInteger = sizeof(char32_t) == sizeof(int) ? 1 : -1 }; }; -#endif - template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > { template <typename T> @@ -91,6 +81,8 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, + T newValue, T *currentValue) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; } template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW; @@ -173,6 +165,29 @@ bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa } template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW +{ + register T tempValue; + register int result; + asm volatile("0:\n" + "ldrex %[tempValue], [%[_q_value]]\n" + "eors %[result], %[tempValue], %[expectedValue]\n" + "itt eq\n" + "strexeq %[result], %[newValue], [%[_q_value]]\n" + "teqeq %[result], #1\n" + "beq 0b\n" + : [result] "=&r" (result), + [tempValue] "=&r" (tempValue), + "+m" (_q_value) + : [expectedValue] "r" (expectedValue), + [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + *currentValue = tempValue; + return result == 0; +} + +template<> template <typename T> inline T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { T originalValue; @@ -220,20 +235,9 @@ T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy || defined(__ARM_ARCH_6K__) // LDREXB, LDREXH and LDREXD are available on ARMv6K or higher -template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; - -# ifdef Q_COMPILER_UNICODE_STRINGS -template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; -# endif +template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; #define Q_ATOMIC_INT8_IS_SUPPORTED #define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE @@ -312,6 +316,29 @@ bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa } template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW +{ + register T tempValue; + register T result; + asm volatile("0:\n" + "ldrexb %[tempValue], [%[_q_value]]\n" + "eors %[result], %[tempValue], %[expectedValue]\n" + "itt eq\n" + "strexbeq %[result], %[newValue], [%[_q_value]]\n" + "teqeq %[result], #1\n" + "beq 0b\n" + : [result] "=&r" (result), + [tempValue] "=&r" (tempValue), + "+m" (_q_value) + : [expectedValue] "r" (expectedValue), + [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + *currentValue = tempValue; + return result == 0; +} + +template<> template <typename T> inline T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { T originalValue; @@ -411,6 +438,29 @@ bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa } template<> template <typename T> inline +bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW +{ + register T tempValue; + register T result; + asm volatile("0:\n" + "ldrexh %[tempValue], [%[_q_value]]\n" + "eors %[result], %[tempValue], %[expectedValue]\n" + "itt eq\n" + "strexheq %[result], %[newValue], [%[_q_value]]\n" + "teqeq %[result], #1\n" + "beq 0b\n" + : [result] "=&r" (result), + [tempValue] "=&r" (tempValue), + "+m" (_q_value) + : [expectedValue] "r" (expectedValue), + [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + *currentValue = tempValue; + return result == 0; +} + +template<> template <typename T> inline T QBasicAtomicOps<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { T originalValue; @@ -522,6 +572,31 @@ bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa } template<> template <typename T> inline +bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW +{ + register T tempValue; + register T result; + asm volatile("0:\n" + "ldrexd %[tempValue], %H[tempValue], [%[_q_value]]\n" + "eor %[result], %[tempValue], %[expectedValue]\n" + "eor %H[result], %H[tempValue], %H[expectedValue]\n" + "orrs %[result], %[result], %H[result]\n" + "itt eq\n" + "strexdeq %[result], %[newValue], %H[newValue], [%[_q_value]]\n" + "teqeq %[result], #1\n" + "beq 0b\n" + : [result] "=&r" (result), + [tempValue] "=&r" (tempValue), + "+m" (_q_value) + : [expectedValue] "r" (expectedValue), + [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + *currentValue = tempValue; + return quint32(result) == 0; +} + +template<> template <typename T> inline T QBasicAtomicOps<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { T originalValue; diff --git a/src/corelib/arch/qatomic_bfin.h b/src/corelib/arch/qatomic_bfin.h deleted file mode 100644 index 79519308a4..0000000000 --- a/src/corelib/arch/qatomic_bfin.h +++ /dev/null @@ -1,350 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_BFIN_H -#define QATOMIC_BFIN_H - -#include <QtCore/qoldbasicatomic.h> - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) - -QT_BEGIN_INCLUDE_NAMESPACE -#include <asm/fixed_code.h> -QT_END_INCLUDE_NAMESPACE - -inline bool QBasicAtomicInt::ref() -{ - int ret; - asm volatile("R0 = 1;\n\t" - "P0 = %3;\n\t" - "CALL (%2);\n\t" - "%0 = R0;" - : "=da" (ret), "=m" (_q_value) - : "a" (ATOMIC_ADD32), "da" (&_q_value), "m" (_q_value) - : "R0", "R1", "P0", "RETS", "memory"); - return ret != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - int ret; - asm volatile("R0 = 1;\n\t" - "P0 = %3;\n\t" - "CALL (%2);\n\t" - "%0 = R0;" - : "=da" (ret), "=m" (_q_value) - : "a" (ATOMIC_SUB32), "da" (&_q_value), "m" (_q_value) - : "R0", "R1", "P0", "RETS", "memory"); - return ret != 0; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - long int readval; - asm volatile ("P0 = %2;\n\t" - "R1 = %3;\n\t" - "R2 = %4;\n\t" - "CALL (%5);\n\t" - "%0 = R0;\n\t" - : "=da" (readval), "=m" (_q_value) - : "da" (&_q_value), - "da" (expectedValue), - "da" (newValue), - "a" (ATOMIC_CAS32), - "m" (_q_value) - : "P0", "R0", "R1", "R2", "RETS", "memory", "cc"); - return readval == expectedValue; -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - asm volatile("R1 = %2;\n\t" - "P0 = %4;\n\t" - "CALL (%3);\n\t" - "%0 = R0;" - : "=da" (newValue), "=m" (_q_value) - : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value) - : "R0", "R1", "P0", "RETS", "memory"); - return newValue; -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - int ret; - asm volatile("R0 = %[val];\n\t" - "P0 = %[qvalp];\n\t" - "CALL (%[addr]);\n\t" - "%[ret] = R1;" - : [ret] "=da" (ret), "=m" (_q_value) - : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd) - : "R0", "R1", "P0", "RETS", "memory"); - return ret; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - T *readval; - asm volatile ("P0 = %2;\n\t" - "R1 = %3;\n\t" - "R2 = %4;\n\t" - "CALL (%5);\n\t" - "%0 = R0;\n\t" - : "=da" (readval), "=m" (_q_value) - : "da" (&_q_value), - "da" (expectedValue), - "da" (newValue), - "a" (ATOMIC_CAS32), - "m" (_q_value) - : "P0", "R0", "R1", "R2", "RETS", "memory", "cc"); - return readval == expectedValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - asm volatile("R1 = %2;\n\t" - "P0 = %4;\n\t" - "CALL (%3);\n\t" - "%0 = R0;" - : "=da" (newValue), "=m" (_q_value) - : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value) - : "R0", "R1", "P0", "RETS", "memory"); - return newValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - T* ret; - asm volatile("R0 = %[val];\n\t" - "P0 = %[qvalp];\n\t" - "CALL (%[addr]);\n\t" - "%[ret] = R1;" - : [ret] "=da" (ret), "=m" (_q_value) - : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd * sizeof(T)) - : "R0", "R1", "P0", "RETS", "memory"); - return ret; -} - - -#endif // Q_OS_LINUX && Q_CC_GNU - -// Test and set for integers - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for integers - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for integers - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -// Test and set for pointers - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE - -#endif // QATOMIC_BFIN_H diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h index 160e0abdf3..7f17387c9c 100644 --- a/src/corelib/arch/qatomic_bootstrap.h +++ b/src/corelib/arch/qatomic_bootstrap.h @@ -54,7 +54,6 @@ QT_END_NAMESPACE #pragma qt_sync_stop_processing #endif -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> > { typedef T Type; diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h index 55e71e1e88..b07e470484 100644 --- a/src/corelib/arch/qatomic_cxx11.h +++ b/src/corelib/arch/qatomic_cxx11.h @@ -70,22 +70,9 @@ QT_END_NAMESPACE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; - -# ifdef Q_COMPILER_UNICODE_STRINGS -template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; -# endif +template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; #define Q_ATOMIC_INT8_IS_SUPPORTED #define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE @@ -162,28 +149,40 @@ template <typename X> struct QAtomicOps static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } - template <typename T> static - bool testAndSetRelaxed(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW + template <typename T> + static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW { - return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed); + if (currentValue) + *currentValue = expectedValue; + return tmp; } template <typename T> - static bool testAndSetAcquire(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW + static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW { - return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire); + if (currentValue) + *currentValue = expectedValue; + return tmp; } template <typename T> - static bool testAndSetRelease(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW + static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW { - return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release); + if (currentValue) + *currentValue = expectedValue; + return tmp; } template <typename T> - static bool testAndSetOrdered(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW + static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW { - return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel); + if (currentValue) + *currentValue = expectedValue; + return tmp; } static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; } diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h index 61e709655d..5184293465 100644 --- a/src/corelib/arch/qatomic_gcc.h +++ b/src/corelib/arch/qatomic_gcc.h @@ -53,12 +53,6 @@ QT_END_NAMESPACE #pragma qt_sync_stop_processing #endif -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -#ifdef Q_COMPILER_UNICODE_STRINGS -template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; -#endif - #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 @@ -75,6 +69,15 @@ template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +#if QT_POINTER_SIZE == 8 +# define Q_ATOMIC_INT64_IS_SUPPORTED +# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT64_TEST_AND_SET_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; +#endif + template <typename X> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<X> > { // The GCC intrinsics all have fully-ordered memory semantics, so we define @@ -110,6 +113,17 @@ template <typename X> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<X> > } template <typename T> + static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW + { + bool tmp = __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue); + if (tmp) + *currentValue = expectedValue; + else + *currentValue = _q_value; + return tmp; + } + + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { return __sync_lock_test_and_set(&_q_value, newValue); diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h index 98937c7551..e5e93ec2b7 100644 --- a/src/corelib/arch/qatomic_ia64.h +++ b/src/corelib/arch/qatomic_ia64.h @@ -123,22 +123,9 @@ QT_END_NAMESPACE #define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; - -# ifdef Q_COMPILER_UNICODE_STRINGS -template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; -# endif +template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > { @@ -163,10 +150,10 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; } - template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; - template <typename T> static bool testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; - template <typename T> static bool testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; - template <typename T> static bool testAndSetOrdered(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; + template <typename T> static bool testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; + template <typename T> static bool testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; + template <typename T> static bool testAndSetOrdered(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; } @@ -302,7 +289,7 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValu x = &_q_value; T *expectedValueCopy = expectedValue; return (_InterlockedCompareExchange64_acq(p, quintptr(newValue), quintptr(expectedValueCopy)) - == quintptr(expectedValue)); + == quintptr(expectedValue)); } template <typename T> @@ -315,7 +302,7 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValu x = &_q_value; T *expectedValueCopy = expectedValue; return (_InterlockedCompareExchange64_rel(p, quintptr(newValue), quintptr(expectedValueCopy)) - == quintptr(expectedValue)); + == quintptr(expectedValue)); } template <typename T> @@ -386,7 +373,7 @@ bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW } template<> template <typename T> inline -bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -395,11 +382,13 @@ bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } template<> template <typename T> inline -bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -408,11 +397,13 @@ bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } template<> template <typename T> inline -bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -421,11 +412,13 @@ bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } template<> template <typename T> inline -bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -434,11 +427,13 @@ bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } template<> template <typename T> inline -bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -447,11 +442,13 @@ bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } template<> template <typename T> inline -bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -460,11 +457,13 @@ bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } template<> template <typename T> inline -bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -473,11 +472,13 @@ bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } template<> template <typename T> inline -bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T ret; asm volatile("mov ar.ccv=%2\n" @@ -486,6 +487,8 @@ bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newVa : "=r" (ret), "+m" (_q_value) : "r" (expectedValue), "r" (newValue) : "memory"); + if (currentValue) + *currentValue = ret; return ret == expectedValue; } diff --git a/src/corelib/arch/qatomic_integrity.h b/src/corelib/arch/qatomic_integrity.h deleted file mode 100644 index f8cfc8ce5b..0000000000 --- a/src/corelib/arch/qatomic_integrity.h +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_INTEGRITY_H -#define QATOMIC_INTEGRITY_H - -#include <QtCore/qoldbasicatomic.h> -#include <INTEGRITY.h> - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define qt_i2addr(a) reinterpret_cast<Address *>(const_cast<int *>(a)) -#define qt_p2addr(a) reinterpret_cast<Address *>(const_cast<void *>(a)) -#define qt_addr(a) reinterpret_cast<Address>(a) - - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return true; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return true; } - -// Reference counting - -inline bool QBasicAtomicInt::ref() -{ - int oldval; - AtomicModify(qt_i2addr(&_q_value), qt_i2addr(&oldval), 0, 1); - return _q_value != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - int oldval; - AtomicModify(qt_i2addr(&_q_value), qt_i2addr(&oldval), 0, -1U); - return _q_value != 0; -} - -// Test and set for integers - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return TestAndSet(qt_i2addr(&_q_value), expectedValue, newValue) == Success; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for integers - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - int old_val; - do { - old_val = _q_value; - } while (TestAndSet(qt_i2addr(&_q_value), old_val, newValue) != Success); - return old_val; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for integers - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - int old_val; - do { - old_val = _q_value; - } while (TestAndSet(qt_i2addr(&_q_value), old_val, old_val + valueToAdd) != Success); - return old_val; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -// Test and set for pointers - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return TestAndSet((Address*)&_q_value, qt_addr(expectedValue), qt_addr(newValue)) == Success; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - Address old_val; - do { - old_val = *reinterpret_cast<Address *>(const_cast<T *>(newValue)); - } while (TestAndSet(reinterpret_cast<Address *>(const_cast<T **>(&_q_value)), old_val, qt_addr(newValue)) != Success); - return reinterpret_cast<T *>(old_val); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - AtomicModify(qt_p2addr(&_q_value), qt_addr(_q_value), qt_addr(_q_value) + valueToAdd * sizeof(T)); - return _q_value; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE - -#endif // QATOMIC_INTEGRITY_H - diff --git a/src/corelib/arch/qatomic_mips.h b/src/corelib/arch/qatomic_mips.h index 6eb9613e31..463612212b 100644 --- a/src/corelib/arch/qatomic_mips.h +++ b/src/corelib/arch/qatomic_mips.h @@ -69,16 +69,6 @@ QT_END_NAMESPACE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -#if defined(Q_COMPILER_UNICODE_STRINGS) && !defined(Q_PROCESSOR_MIPS_64) -// for MIPS32, ensure that char32_t (an uint_least32_t), is 32-bit -// it's extremely unlikely it won't be on a 32-bit MIPS, but just to be sure -// For MIPS64, we're sure it works, but the definition is below -template<> struct QAtomicIntegerTraits<char32_t> -{ enum { IsInteger = sizeof(char32_t) == sizeof(int) ? 1 : -1 }; }; -#endif - template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > { template <typename T> @@ -94,7 +84,8 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } - template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; + template <typename T> static bool + testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; } template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW; @@ -173,13 +164,13 @@ bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW } template<> template <typename T> inline -bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T result; T tempValue; asm volatile("0:\n" - "ll %[result], %[_q_value]\n" - "xor %[result], %[result], %[expectedValue]\n" + "ll %[tempValue], %[_q_value]\n" + "xor %[result], %[tempValue], %[expectedValue]\n" "bnez %[result], 0f\n" "nop\n" "move %[tempValue], %[newValue]\n" @@ -193,6 +184,8 @@ bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa : [expectedValue] "r" (expectedValue), [newValue] "r" (newValue) : "cc", "memory"); + if (currentValue) + *currentValue = tempValue; return result == 0; } @@ -242,14 +235,7 @@ T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy #define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE -template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long long > { enum { IsInteger = 1 }; }; - -#ifdef Q_COMPILER_UNICODE_STRINGS -template<> struct QAtomicIntegerTraits<char16_t> -{ enum { IsInteger = sizeof(char16_t) == sizeof(int) ? 1 : -1 }; }; -template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; -#endif +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; template<> template<typename T> inline bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW @@ -290,13 +276,13 @@ bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW } template<> template <typename T> inline -bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { T result; T tempValue; asm volatile("0:\n" - "lld %[result], %[_q_value]\n" - "xor %[result], %[result], %[expectedValue]\n" + "lld %[tempValue], %[_q_value]\n" + "xor %[result], %[tempValue], %[expectedValue]\n" "bnez %[result], 0f\n" "nop\n" "move %[tempValue], %[newValue]\n" @@ -310,6 +296,8 @@ bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa : [expectedValue] "r" (expectedValue), [newValue] "r" (newValue) : "cc", "memory"); + if (currentValue) + *currentValue = tempValue; return result == 0; } diff --git a/src/corelib/arch/qatomic_msvc.h b/src/corelib/arch/qatomic_msvc.h index 4f91e3d9da..c660f78888 100644 --- a/src/corelib/arch/qatomic_msvc.h +++ b/src/corelib/arch/qatomic_msvc.h @@ -53,6 +53,11 @@ # define QT_INTERLOCKED_PROTOTYPE __cdecl # define QT_INTERLOCKED_DECLARE_PROTOTYPES # define QT_INTERLOCKED_INTRINSIC +# define Q_ATOMIC_INT16_IS_SUPPORTED + +# ifdef _WIN64 +# define Q_ATOMIC_INT64_IS_SUPPORTED +# endif #else // Q_OS_WINCE @@ -130,6 +135,20 @@ extern "C" { __int64 QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64); # endif +# ifdef Q_ATOMIC_INT16_IS_SUPPORTED + short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment16 )(short QT_INTERLOCKED_VOLATILE *); + short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement16 )(short QT_INTERLOCKED_VOLATILE *); + short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange16 )(short QT_INTERLOCKED_VOLATILE *, short, short); + short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange16 )(short QT_INTERLOCKED_VOLATILE *, short); + short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd16 )(short QT_INTERLOCKED_VOLATILE *, short); +# endif +# ifdef Q_ATOMIC_INT64_IS_SUPPORTED + __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment64 )(__int64 QT_INTERLOCKED_VOLATILE *); + __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement64 )(__int64 QT_INTERLOCKED_VOLATILE *); + __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64, __int64); + __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64); + //above already: qint64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )(qint64 QT_INTERLOCKED_VOLATILE *, qint64); +# endif } #endif // QT_INTERLOCKED_DECLARE_PROTOTYPES @@ -158,21 +177,6 @@ extern "C" { //////////////////////////////////////////////////////////////////////////////////////////////////// // Interlocked* replacement macros -#define QT_INTERLOCKED_INCREMENT(value) \ - QT_INTERLOCKED_FUNCTION(Increment)(value) - -#define QT_INTERLOCKED_DECREMENT(value) \ - QT_INTERLOCKED_FUNCTION(Decrement)(value) - -#define QT_INTERLOCKED_COMPARE_EXCHANGE(value, newValue, expectedValue) \ - QT_INTERLOCKED_FUNCTION(CompareExchange)((value), (newValue), (expectedValue)) - -#define QT_INTERLOCKED_EXCHANGE(value, newValue) \ - QT_INTERLOCKED_FUNCTION(Exchange)((value), (newValue)) - -#define QT_INTERLOCKED_EXCHANGE_ADD(value, valueToAdd) \ - QT_INTERLOCKED_FUNCTION(ExchangeAdd)((value), (valueToAdd)) - #if defined(Q_OS_WINCE) || defined(__i386__) || defined(_M_IX86) # define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \ @@ -258,72 +262,194 @@ QT_END_NAMESPACE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE -//////////////////////////////////////////////////////////////////////////////////////////////////// +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_WAIT_FREE + +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_TEST_AND_SET_IS_WAIT_FREE + +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_WAIT_FREE -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; -#ifdef Q_COMPILER_UNICODE_STRINGS -template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE + +template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; #endif -// No definition, needs specialization -template <int N> struct QAtomicOpsBySize; +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED +# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_WAIT_FREE -template <> -struct QAtomicOpsBySize<4> : QGenericAtomicOps<QAtomicOpsBySize<4> > -{ - // The 32-bit Interlocked*() API takes parameters as longs. - typedef long Type; +# define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT64_TEST_AND_SET_IS_WAIT_FREE + +# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_WAIT_FREE + +# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE +# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE + +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template <int N> struct QAtomicWindowsType { typedef typename QIntegerForSize<N>::Signed Type; }; +template <> struct QAtomicWindowsType<4> { typedef long Type; }; + + +template <int N> struct QAtomicOpsBySize : QGenericAtomicOps<QAtomicOpsBySize<N> > +{ static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return true; } - static bool ref(long &_q_value) Q_DECL_NOTHROW; - static bool deref(long &_q_value) Q_DECL_NOTHROW; + template <typename T> static bool ref(T &_q_value) Q_DECL_NOTHROW; + template <typename T> static bool deref(T &_q_value) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; } - static bool testAndSetRelaxed(long &_q_value, long expectedValue, long newValue) Q_DECL_NOTHROW; + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; + template <typename T> + static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; } - static long fetchAndStoreRelaxed(long &_q_value, long newValue) Q_DECL_NOTHROW; + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return true; } - static long fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd) Q_DECL_NOTHROW; + template <typename T> static T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW; + +private: + typedef typename QAtomicWindowsType<N>::Type Type; + template <typename T> static inline Type *atomic(T *t) + { Q_STATIC_ASSERT(sizeof(T) == sizeof(Type)); return reinterpret_cast<Type *>(t); } + template <typename T> static inline Type value(T t) + { Q_STATIC_ASSERT(sizeof(T) == sizeof(Type)); return Type(t); } }; template <typename T> struct QAtomicOps : QAtomicOpsBySize<sizeof(T)> -{ }; +{ + typedef T Type; +}; + +template<> template<typename T> +inline bool QAtomicOpsBySize<4>::ref(T &_q_value) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(Increment)(atomic(&_q_value)) != 0; +} + +template<> template<typename T> +inline bool QAtomicOpsBySize<4>::deref(T &_q_value) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(Decrement)(atomic(&_q_value)) != 0; +} + +template<> template<typename T> +inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue); +} + +template<> template <typename T> +inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW +{ + *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), newValue, expectedValue)); + return *currentValue == expectedValue; +} + +template<> template<typename T> +inline T QAtomicOpsBySize<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(Exchange)(atomic(&_q_value), value(newValue)); +} + +template<> template<typename T> +inline T QAtomicOpsBySize<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(ExchangeAdd)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale)); +} + +#ifdef Q_ATOMIC_INT16_IS_SUPPORTED +template<> template<typename T> +inline bool QAtomicOpsBySize<2>::ref(T &_q_value) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(Increment16)(atomic(&_q_value)) != 0; +} + +template<> template<typename T> +inline bool QAtomicOpsBySize<2>::deref(T &_q_value) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(Decrement16)(atomic(&_q_value)) != 0; +} -inline bool QAtomicOpsBySize<4>::ref(long &_q_value) Q_DECL_NOTHROW +template<> template<typename T> +inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW { - return QT_INTERLOCKED_INCREMENT(&_q_value) != 0; + return QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue); } -inline bool QAtomicOpsBySize<4>::deref(long &_q_value) Q_DECL_NOTHROW +template<> template <typename T> +inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW { - return QT_INTERLOCKED_DECREMENT(&_q_value) != 0; + *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), newValue, expectedValue)); + return *currentValue == expectedValue; } -inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(long &_q_value, long expectedValue, long newValue) Q_DECL_NOTHROW +template<> template<typename T> +inline T QAtomicOpsBySize<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { - return QT_INTERLOCKED_COMPARE_EXCHANGE(&_q_value, newValue, expectedValue) == expectedValue; + return QT_INTERLOCKED_FUNCTION(Exchange16)(atomic(&_q_value), value(newValue)); } -inline long QAtomicOpsBySize<4>::fetchAndStoreRelaxed(long &_q_value, long newValue) Q_DECL_NOTHROW +template<> template<typename T> +inline T QAtomicOpsBySize<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(ExchangeAdd16)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale)); +} +#endif + +#ifdef Q_ATOMIC_INT64_IS_SUPPORTED +template<> template<typename T> +inline bool QAtomicOpsBySize<8>::ref(T &_q_value) Q_DECL_NOTHROW { - return QT_INTERLOCKED_EXCHANGE(&_q_value, newValue); + return QT_INTERLOCKED_FUNCTION(Increment64)(atomic(&_q_value)) != 0; } -inline long QAtomicOpsBySize<4>::fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd) Q_DECL_NOTHROW +template<> template<typename T> +inline bool QAtomicOpsBySize<8>::deref(T &_q_value) Q_DECL_NOTHROW { - return QT_INTERLOCKED_EXCHANGE_ADD(&_q_value, valueToAdd * QAtomicAdditiveType<long>::AddScale); + return QT_INTERLOCKED_FUNCTION(Decrement64)(atomic(&_q_value)) != 0; } +template<> template<typename T> +inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue); +} + +template<> template <typename T> +inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW +{ + *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), newValue, expectedValue)); + return *currentValue == expectedValue; +} + +template<> template<typename T> +inline T QAtomicOpsBySize<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(Exchange64)(atomic(&_q_value), value(newValue)); +} + +template<> template<typename T> +inline T QAtomicOpsBySize<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW +{ + return QT_INTERLOCKED_FUNCTION(ExchangeAdd64)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale)); +} +#endif + // Specialization for pointer types, since we have Interlocked*Pointer() variants in some configurations template <typename T> struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> > @@ -333,6 +459,7 @@ struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> > static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; } static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) Q_DECL_NOTHROW; + static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; } @@ -350,6 +477,13 @@ inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T } template <typename T> +inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW +{ + *currentValue = reinterpret_cast<T *>(QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue)); + return *currentValue == expectedValue; +} + +template <typename T> inline T *QAtomicOps<T *>::fetchAndStoreRelaxed(T *&_q_value, T *newValue) Q_DECL_NOTHROW { return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, newValue)); diff --git a/src/corelib/arch/qatomic_power.h b/src/corelib/arch/qatomic_power.h deleted file mode 100644 index 3ddd303795..0000000000 --- a/src/corelib/arch/qatomic_power.h +++ /dev/null @@ -1,521 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_POWER_H -#define QATOMIC_POWER_H - -#include <QtCore/qoldbasicatomic.h> - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -#if defined(Q_CC_GNU) - -#ifdef Q_PROCESSOR_POWER_32 -# define _Q_VALUE "0, %[_q_value]" -# define _Q_VALUE_MEMORY_OPERAND "+m" (_q_value) -# define _Q_VALUE_REGISTER_OPERAND [_q_value] "r" (&_q_value), -#else // Q_PROCESSOR_POWER_64 -# define _Q_VALUE "%y[_q_value]" -# define _Q_VALUE_MEMORY_OPERAND [_q_value] "+Z" (_q_value) -# define _Q_VALUE_REGISTER_OPERAND -#endif - -inline bool QBasicAtomicInt::ref() -{ - int originalValue; - int newValue; - asm volatile("lwarx %[originalValue]," _Q_VALUE "\n" - "addi %[newValue], %[originalValue], %[one]\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - : [originalValue] "=&b" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [one] "i" (1) - : "cc", "memory"); - return newValue != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - int originalValue; - int newValue; - asm volatile("lwarx %[originalValue]," _Q_VALUE "\n" - "addi %[newValue], %[originalValue], %[minusOne]\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - : [originalValue] "=&b" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [minusOne] "i" (-1) - : "cc", "memory"); - return newValue != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - int result; - asm volatile("lwarx %[result]," _Q_VALUE "\n" - "xor. %[result], %[result], %[expectedValue]\n" - "bne $+12\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-16\n" - : [result] "=&r" (result), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - int result; - asm volatile("lwarx %[result]," _Q_VALUE "\n" - "xor. %[result], %[result], %[expectedValue]\n" - "bne $+16\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-16\n" - "isync\n" - : [result] "=&r" (result), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - int result; - asm volatile("eieio\n" - "lwarx %[result]," _Q_VALUE "\n" - "xor. %[result], %[result], %[expectedValue]\n" - "bne $+12\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-16\n" - : [result] "=&r" (result), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - int originalValue; - asm volatile("lwarx %[originalValue]," _Q_VALUE "\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-8\n" - : [originalValue] "=&r" (originalValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - int originalValue; - asm volatile("lwarx %[originalValue]," _Q_VALUE "\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-8\n" - "isync\n" - : [originalValue] "=&r" (originalValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - int originalValue; - asm volatile("eieio\n" - "lwarx %[originalValue]," _Q_VALUE "\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-8\n" - : [originalValue] "=&r" (originalValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - int originalValue; - int newValue; - asm volatile("lwarx %[originalValue]," _Q_VALUE "\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [valueToAdd] "r" (valueToAdd) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - int originalValue; - int newValue; - asm volatile("lwarx %[originalValue]," _Q_VALUE "\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - "isync\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [valueToAdd] "r" (valueToAdd) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - int originalValue; - int newValue; - asm volatile("eieio\n" - "lwarx %[originalValue]," _Q_VALUE "\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - "stwcx. %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [valueToAdd] "r" (valueToAdd) - : "cc", "memory"); - return originalValue; -} - -#ifdef Q_PROCESSOR_POWER_64 -# define LPARX "ldarx" -# define STPCX "stdcx." -#else -# define LPARX "lwarx" -# define STPCX "stwcx." -#endif - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - void *result; - asm volatile(LPARX" %[result]," _Q_VALUE "\n" - "xor. %[result], %[result], %[expectedValue]\n" - "bne $+12\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-16\n" - : [result] "=&r" (result), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - void *result; - asm volatile(LPARX" %[result]," _Q_VALUE "\n" - "xor. %[result], %[result], %[expectedValue]\n" - "bne $+16\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-16\n" - "isync\n" - : [result] "=&r" (result), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - void *result; - asm volatile("eieio\n" - LPARX" %[result]," _Q_VALUE "\n" - "xor. %[result], %[result], %[expectedValue]\n" - "bne $+12\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-16\n" - : [result] "=&r" (result), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - T *originalValue; - asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-8\n" - : [originalValue] "=&r" (originalValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - T *originalValue; - asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-8\n" - "isync\n" - : [originalValue] "=&r" (originalValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - T *originalValue; - asm volatile("eieio\n" - LPARX" %[originalValue]," _Q_VALUE "\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-8\n" - : [originalValue] "=&r" (originalValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - T *originalValue; - T *newValue; - asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - T *originalValue; - T *newValue; - asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - "isync\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - T *originalValue; - T *newValue; - asm volatile("eieio\n" - LPARX" %[originalValue]," _Q_VALUE "\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - STPCX" %[newValue]," _Q_VALUE "\n" - "bne- $-12\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - _Q_VALUE_MEMORY_OPERAND - : _Q_VALUE_REGISTER_OPERAND - [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "cc", "memory"); - return originalValue; -} - -#undef LPARX -#undef STPCX -#undef _Q_VALUE -#undef _Q_VALUE_MEMORY_OPERAND -#undef _Q_VALUE_REGISTER_OPERAND - -#else -# error "This compiler for Power/PowerPC is not supported" -#endif - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -QT_END_NAMESPACE - -#endif // QATOMIC_POWER_H diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h deleted file mode 100644 index 0469f44e5f..0000000000 --- a/src/corelib/arch/qatomic_s390.h +++ /dev/null @@ -1,433 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_S390_H -#define QATOMIC_S390_H - -#include <QtCore/qoldbasicatomic.h> - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -#ifdef __GNUC__ -#define __GNU_EXTENSION __extension__ -#else -#define __GNU_EXTENSION -#endif - -#define __CS_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \ - volatile int old_val, new_val; \ - __asm__ __volatile__(pre \ - " l %0,0(%3)\n" \ - "0: lr %1,%0\n" \ - op_string " %1,%4\n" \ - " cs %0,%1,0(%3)\n" \ - " jl 0b\n" \ - post \ - : "=&d" (old_val), "=&d" (new_val), \ - "=m" (*ptr) \ - : "a" (ptr), "d" (op_val), \ - "m" (*ptr) \ - : "cc", "memory" ); \ - new_val; \ -}) - -#define __CS_OLD_LOOP(ptr, op_val, op_string, pre, post ) __GNU_EXTENSION ({ \ - volatile int old_val, new_val; \ - __asm__ __volatile__(pre \ - " l %0,0(%3)\n" \ - "0: lr %1,%0\n" \ - op_string " %1,%4\n" \ - " cs %0,%1,0(%3)\n" \ - " jl 0b\n" \ - post \ - : "=&d" (old_val), "=&d" (new_val), \ - "=m" (*ptr) \ - : "a" (ptr), "d" (op_val), \ - "m" (*ptr) \ - : "cc", "memory" ); \ - old_val; \ -}) - -#ifdef __s390x__ -#define __CSG_OLD_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \ - long old_val, new_val; \ - __asm__ __volatile__(pre \ - " lg %0,0(%3)\n" \ - "0: lgr %1,%0\n" \ - op_string " %1,%4\n" \ - " csg %0,%1,0(%3)\n" \ - " jl 0b\n" \ - post \ - : "=&d" (old_val), "=&d" (new_val), \ - "=m" (*ptr) \ - : "a" (ptr), "d" (op_val), \ - "m" (*ptr) \ - : "cc", "memory" ); \ - old_val; \ -}) -#endif - -inline bool QBasicAtomicInt::ref() -{ - return __CS_LOOP(&_q_value, 1, "ar", "", "") != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - return __CS_LOOP(&_q_value, 1, "sr", "", "") != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - int retval; - __asm__ __volatile__( - " lr %0,%3\n" - " cs %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); - return retval == 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - int retval; - __asm__ __volatile__( - " lr %0,%3\n" - " cs %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:\n" - " bcr 15,0\n" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); - return retval == 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - int retval; - __asm__ __volatile__( - " bcr 15,0\n" - " lr %0,%3\n" - " cs %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); - return retval == 0; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", ""); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "bcr 15,0\n"); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return __CS_OLD_LOOP(&_q_value, newValue, "lr", "bcr 15,0\n", ""); -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return __CS_OLD_LOOP(&_q_value, valueToAdd, "ar", "", "bcr 15,0\n"); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - int retval; - -#ifndef __s390x__ - __asm__ __volatile__( - " lr %0,%3\n" - " cs %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); -#else - __asm__ __volatile__( - " lgr %0,%3\n" - " csg %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); -#endif - - return retval == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - int retval; - -#ifndef __s390x__ - __asm__ __volatile__( - " lr %0,%3\n" - " cs %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:\n" - " bcr 15,0\n" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); -#else - __asm__ __volatile__( - " lgr %0,%3\n" - " csg %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:\n" - " bcr 15,0\n" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); -#endif - - return retval == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - int retval; - -#ifndef __s390x__ - __asm__ __volatile__( - " bcr 15,0\n" - " lr %0,%3\n" - " cs %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); -#else - __asm__ __volatile__( - " bcr 15,0\n" - " lgr %0,%3\n" - " csg %0,%4,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - "0:" - : "=&d" (retval), "=m" (_q_value) - : "a" (&_q_value), "d" (expectedValue) , "d" (newValue), - "m" (_q_value) : "cc", "memory" ); -#endif - - return retval == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ -#ifndef __s390x__ - return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", ""); -#else - return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", ""); -#endif -} - -template <typename T> -Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ -#ifndef __s390x__ - return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n"); -#else - return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n"); -#endif -} - -template <typename T> -Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ -#ifndef __s390x__ - return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", ""); -#else - return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", ""); -#endif -} - -template <typename T> -Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return fetchAndStoreAcquire(newValue); -} - - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -#undef __GNU_EXTENSION - -QT_END_NAMESPACE - -#endif // QATOMIC_S390_H diff --git a/src/corelib/arch/qatomic_sh4a.h b/src/corelib/arch/qatomic_sh4a.h deleted file mode 100644 index 6e59279f3e..0000000000 --- a/src/corelib/arch/qatomic_sh4a.h +++ /dev/null @@ -1,540 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_SH4A_H -#define QATOMIC_SH4A_H - -#include <QtCore/qoldbasicatomic.h> - -QT_BEGIN_NAMESPACE - - -QT_END_NAMESPACE - -#if 0 -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -QT_BEGIN_NAMESPACE - -#if !defined(Q_CC_GNU) -# error "SH-4A support has not been added for this compiler" -#else - -inline bool QBasicAtomicInt::ref() -{ - register int newValue asm("r0"); - asm volatile("0:\n" - "movli.l @%[_q_value], %[newValue]\n" - "add #1,%[newValue]\n" - "movco.l %[newValue], @%[_q_value]\n" - "bf 0b\n" - : [newValue] "=&r" (newValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - register int newValue asm("r0"); - asm volatile("0:\n" - "movli.l @%[_q_value], %[newValue]\n" - "add #-1,%[newValue]\n" - "movco.l %[newValue], @%[_q_value]\n" - "bf 0b\n" - : [newValue] "=&r" (newValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - int result; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "xor %[expectedValue], r0\n" - "cmp/eq #0, r0\n" - "bf/s 0f\n" - "mov r0, %[result]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "0:\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return result == 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - int result; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "xor %[expectedValue], r0\n" - "cmp/eq #0, r0\n" - "bf/s 0f\n" - "mov r0, %[result]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "synco\n" - "0:\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return result == 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - int result; - asm volatile("synco\n" - "0:\n" - "movli.l @%[_q_value], r0\n" - "xor %[expectedValue], r0\n" - "cmp/eq #0, r0\n" - "bf/s 0f\n" - "mov r0, %[result]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "0:\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return result == 0; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - int originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - int originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "synco\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - int originalValue; - asm volatile("synco\n" - "0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - int originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "add %[valueToAdd], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [valueToAdd] "r" (valueToAdd) - : "r0", "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - int originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "add %[valueToAdd], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "synco\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [valueToAdd] "r" (valueToAdd) - : "r0", "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - int originalValue; - asm volatile("synco\n" - "0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "add %[valueToAdd], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [valueToAdd] "r" (valueToAdd) - : "r0", "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - T *result; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "xor %[expectedValue], r0\n" - "cmp/eq #0, r0\n" - "bf/s 0f\n" - "mov r0, %[result]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "0:\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return result == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - T *result; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "xor %[expectedValue], r0\n" - "cmp/eq #0, r0\n" - "bf/s 0f\n" - "mov r0, %[result]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "synco\n" - "0:\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return result == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - T *result; - asm volatile("synco\n" - "0:\n" - "movli.l @%[_q_value], r0\n" - "xor %[expectedValue], r0\n" - "cmp/eq #0, r0\n" - "bf/s 0f\n" - "mov r0, %[result]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "0:\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return result == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - T *originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - T *originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "synco\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - T *originalValue; - asm volatile("synco\n" - "0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "mov %[newValue], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [newValue] "r" (newValue) - : "r0", "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - T *originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "add %[valueToAdd], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "r0", "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - T *originalValue; - asm volatile("0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "add %[valueToAdd], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - "synco\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "r0", "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - T *originalValue; - asm volatile("synco\n" - "0:\n" - "movli.l @%[_q_value], r0\n" - "mov r0, %[originalValue]\n" - "add %[valueToAdd], r0\n" - "movco.l r0, @%[_q_value]\n" - "bf 0b\n" - : [originalValue] "=&r" (originalValue), - "+m" (_q_value) - : [_q_value] "r" (&_q_value), - [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "r0", "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -#endif // Q_CC_GNU - -#endif // QATOMIC_SH4A_H diff --git a/src/corelib/arch/qatomic_sparc.h b/src/corelib/arch/qatomic_sparc.h deleted file mode 100644 index 8aea33ce85..0000000000 --- a/src/corelib/arch/qatomic_sparc.h +++ /dev/null @@ -1,532 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_SPARC_H -#define QATOMIC_SPARC_H - -#include <QtCore/qoldbasicatomic.h> - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#if defined(_LP64) - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return true; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -extern "C" { - Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr); - Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr); - - Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, - int expected, - int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, - int expected, - int newval); - - Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval); - Q_CORE_EXPORT int q_atomic_fetch_and_store_acquire_int(volatile int *ptr, int newval); - Q_CORE_EXPORT int q_atomic_fetch_and_store_release_int(volatile int *ptr, int newval); - - Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value); - Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value); - Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value); - - Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, const void *expected, const void *newval); - Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, - const void *expected, - const void *newval); - Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr, - const void *expected, - const void *newval); - - Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, const void *newval); - Q_CORE_EXPORT void *q_atomic_fetch_and_store_acquire_ptr(volatile void *ptr, const void *newval); - Q_CORE_EXPORT void *q_atomic_fetch_and_store_release_ptr(volatile void *ptr, const void *newval); - - Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, int value); - Q_CORE_EXPORT void *q_atomic_fetch_and_add_acquire_ptr(volatile void *ptr, int value); - Q_CORE_EXPORT void *q_atomic_fetch_and_add_release_ptr(volatile void *ptr, int value); -} - -inline bool QBasicAtomicInt::ref() -{ - return fetchAndAddRelaxed(1) != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - return fetchAndAddRelaxed(-1) != 1; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return q_atomic_set_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return q_atomic_fetch_and_store_release_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int newValue) -{ - return q_atomic_fetch_and_add_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int newValue) -{ - return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int newValue) -{ - return q_atomic_fetch_and_add_release_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int newValue) -{ - return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T))); -} - -template <typename T> -Q_INLINE_TEMPLATE -T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T))); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, valueToAdd * sizeof(T))); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T))); -} - -#else - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -extern "C" { - Q_CORE_EXPORT int q_atomic_lock_int(volatile int *addr); - Q_CORE_EXPORT int q_atomic_lock_ptr(volatile void *addr); - Q_CORE_EXPORT void q_atomic_unlock(volatile void *addr, int value); - Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval); - Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval); -} // extern "C" - -inline bool QBasicAtomicInt::ref() -{ - const int val = q_atomic_lock_int(&_q_value); - q_atomic_unlock(&_q_value, val + 1); - return val != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - const int val = q_atomic_lock_int(&_q_value); - q_atomic_unlock(&_q_value, val - 1); - return val != 1; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - int val = q_atomic_lock_int(&_q_value); - if (val == expectedValue) { - q_atomic_unlock(&_q_value, newValue); - return true; - } - q_atomic_unlock(&_q_value, val); - return false; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return q_atomic_set_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - const int originalValue = q_atomic_lock_int(&_q_value); - q_atomic_unlock(&_q_value, originalValue + valueToAdd); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - T *val = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value)); - if (val == expectedValue) { - q_atomic_unlock(&_q_value, reinterpret_cast<int>(newValue)); - return true; - } - q_atomic_unlock(&_q_value, reinterpret_cast<int>(val)); - return false; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - T *originalValue = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value)); - q_atomic_unlock(&_q_value, int(originalValue + valueToAdd)); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -#endif // _LP64 - -QT_END_NAMESPACE - -#endif // QATOMIC_SPARC_H diff --git a/src/corelib/arch/qatomic_unix.cpp b/src/corelib/arch/qatomic_unix.cpp index 4acf43d6a5..7a5c48c235 100644 --- a/src/corelib/arch/qatomic_unix.cpp +++ b/src/corelib/arch/qatomic_unix.cpp @@ -65,6 +65,19 @@ bool QAtomicOps<int>::testAndSetRelaxed(int &_q_value, int expectedValue, int ne } Q_CORE_EXPORT +bool QAtomicOps<long long>::testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW +{ + bool returnValue = false; + pthread_mutex_lock(&qAtomicMutex); + if (_q_value == expectedValue) { + _q_value = newValue; + returnValue = true; + } + pthread_mutex_unlock(&qAtomicMutex); + return returnValue; +} + +Q_CORE_EXPORT bool QAtomicOps<void *>::testAndSetRelaxed(void *&_q_value, void *expectedValue, void *newValue) Q_DECL_NOTHROW { bool returnValue = false; diff --git a/src/corelib/arch/qatomic_unix.h b/src/corelib/arch/qatomic_unix.h index 03c7d2eee8..6ed9864073 100644 --- a/src/corelib/arch/qatomic_unix.h +++ b/src/corelib/arch/qatomic_unix.h @@ -59,16 +59,25 @@ QT_END_NAMESPACE #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE #define Q_ATOMIC_INT32_IS_SUPPORTED +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NOT_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NOT_NATIVE + +#define Q_ATOMIC_INT64_IS_SUPPORTED +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_NOT_NATIVE +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_NOT_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; - // No definition, needs specialization template <typename T> struct QAtomicOps; +// 32-bit version template <> struct QAtomicOps<int> : QGenericAtomicOps<QAtomicOps<int> > { @@ -79,6 +88,18 @@ struct QAtomicOps<int> : QGenericAtomicOps<QAtomicOps<int> > Q_CORE_EXPORT static bool testAndSetRelaxed(int &_q_value, int expectedValue, int newValue) Q_DECL_NOTHROW; }; +// 64-bit version +template <> +struct QAtomicOps<long long> : QGenericAtomicOps<QAtomicOps<long long> > +{ + typedef long long Type; + + static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; } + static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } + Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW; +}; + +// pointer version template <> struct QAtomicOps<void *> : QGenericAtomicOps<QAtomicOps<void *> > { @@ -109,5 +130,23 @@ struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> > } }; +// 32- and 64-bit unsigned versions +template <> struct QAtomicOps<unsigned> : QAtomicOps<int> +{ + typedef unsigned Type; + Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW + { + return QAtomicOps<int>::testAndSetRelaxed(reinterpret_cast<int &>(_q_value), int(expectedValue), int(newValue)); + } +}; +template <> struct QAtomicOps<unsigned long long> : QAtomicOps<long long> +{ + typedef unsigned long longType; + Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW + { + return QAtomicOps<long long>::testAndSetRelaxed(reinterpret_cast<long long &>(_q_value), int(expectedValue), int(newValue)); + } +}; + QT_END_NAMESPACE #endif // QATOMIC_UNIX_H diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h deleted file mode 100644 index 57e3b6a32b..0000000000 --- a/src/corelib/arch/qatomic_vxworks.h +++ /dev/null @@ -1,330 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_VXWORKS_H -#define QATOMIC_VXWORKS_H - -#if defined(__ppc) -# include <QtCore/qatomic_power.h> -#else // generic implementation with taskLock() - -#include <QtCore/qoldbasicatomic.h> - -#if 0 -// we don't want to include the system header here for two function prototypes, -// because it pulls in a _lot_ of stuff that pollutes the global namespace -# include <vxWorksCommon.h> -# include <taskLib.h> -#else -#if defined(_WRS_KERNEL) -extern "C" int taskLock(); -extern "C" int taskUnlock(); -#else -inline int taskLock() { return 0; } -inline int taskUnlock() { return 0; } -#endif -#endif - - - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -QT_END_HEADER - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return false; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -// Reference counting - -inline bool QBasicAtomicInt::ref() -{ - taskLock(); - bool ret = (++_q_value != 0); - taskUnlock(); - return ret; -} - -inline bool QBasicAtomicInt::deref() -{ - taskLock(); - bool ret = (--_q_value != 0); - taskUnlock(); - return ret; -} - -// Test-and-set for integers - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - taskLock(); - if (_q_value == expectedValue) { - _q_value = newValue; - taskUnlock(); - return true; - } - taskUnlock(); - return false; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch-and-store for integers - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - taskLock(); - int returnValue = _q_value; - _q_value = newValue; - taskUnlock(); - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch-and-add for integers - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - taskLock(); - int originalValue = _q_value; - _q_value += valueToAdd; - taskUnlock(); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -// Test and set for pointers - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - taskLock(); - if (_q_value == expectedValue) { - _q_value = newValue; - taskUnlock(); - return true; - } - taskUnlock(); - return false; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - taskLock(); - T *returnValue = (_q_value); - _q_value = newValue; - taskUnlock(); - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - taskLock(); - T *returnValue = (_q_value); - _q_value += valueToAdd; - taskUnlock(); - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE - -#endif // generic implementation with taskLock() - -#endif // QATOMIC_VXWORKS_H diff --git a/src/corelib/arch/qatomic_x86.h b/src/corelib/arch/qatomic_x86.h index f8180ad9d6..e3cb296527 100644 --- a/src/corelib/arch/qatomic_x86.h +++ b/src/corelib/arch/qatomic_x86.h @@ -89,9 +89,6 @@ QT_END_NAMESPACE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE -template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; - template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > { static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; } @@ -102,6 +99,8 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; } template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; + template <typename T> static bool + testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW; static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; } static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; } @@ -120,21 +119,9 @@ template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> #if defined(Q_CC_GNU) -template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; - -# ifdef Q_COMPILER_UNICODE_STRINGS -template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; }; -template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; }; -# endif - +template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; +template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; /* * Guide for the inline assembly below: @@ -268,6 +255,36 @@ bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa } template<int size> template <typename T> inline +bool QBasicAtomicOps<size>::testAndSetRelaxed(T &_q_value, T expectedValue, + T newValue, T *currentValue) Q_DECL_NOTHROW +{ + unsigned char ret; + asm volatile("lock\n" + "cmpxchg %3,%2\n" + "sete %1\n" + : "=a" (newValue), "=qm" (ret), "+m" (_q_value) + : "r" (newValue), "0" (expectedValue) + : "memory"); + *currentValue = newValue; + return ret != 0; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, + T newValue, T *currentValue) Q_DECL_NOTHROW +{ + unsigned char ret; + asm volatile("lock\n" + "cmpxchg %3,%2\n" + "sete %1\n" + : "=a" (newValue), "=qm" (ret), "+m" (_q_value) + : "q" (newValue), "0" (expectedValue) + : "memory"); + *currentValue = newValue; + return ret != 0; +} + +template<int size> template <typename T> inline T QBasicAtomicOps<size>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { asm volatile("xchg %0,%1" @@ -339,6 +356,8 @@ T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy #define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE +#ifdef Q_PROCESSOR_X86_64 + #define Q_ATOMIC_INT64_IS_SUPPORTED #define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE @@ -353,7 +372,6 @@ T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy #define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE -#ifdef Q_PROCESSOR_X86_64 // native support for 64-bit types template<> template<typename T> inline bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW |