From 7ffcafd1b5baab0cbb6022ae7b9d4ca1bd76c353 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 8 Jul 2015 17:20:06 -0700 Subject: Remove all the atomic code besides MSVC and std::atomic [ChangeLog][Important Behavior Changes] Starting with Qt 5.7, Qt requires a C++11 compiler with support for C++11 atomics. This affects user code too: Qt headers no longer compile with a C++98 compiler. The minimum compiler versions for this release are: * Clang 3.4 (found in XCode 5.1) * GCC 4.7 * Microsoft Visual Studio 2012 Change-Id: Ib056b47dde3341ef9a52ffff13ef1f496ea9363f Reviewed-by: Marc Mutz Reviewed-by: Dmitry Shachnev --- src/corelib/arch/arch.pri | 12 - src/corelib/arch/qatomic_armv5.h | 210 ---- src/corelib/arch/qatomic_armv6.h | 839 --------------- src/corelib/arch/qatomic_armv7.h | 63 -- src/corelib/arch/qatomic_gcc.h | 151 --- src/corelib/arch/qatomic_ia64.h | 1090 -------------------- src/corelib/arch/qatomic_unix.cpp | 93 -- src/corelib/arch/qatomic_unix.h | 150 --- src/corelib/arch/qatomic_x86.h | 439 -------- src/corelib/arch/sparc/arch.pri | 10 - src/corelib/arch/sparc/qatomic32.s | 101 -- src/corelib/arch/sparc/qatomic64.s | 325 ------ src/corelib/arch/sparc/qatomic_sparc.cpp | 90 -- src/corelib/thread/qbasicatomic.h | 32 +- .../thread/qatomicinteger/gcc/char/char.pro | 1 - .../qatomicinteger/gcc/char16_t/char16_t.pro | 1 - .../qatomicinteger/gcc/char32_t/char32_t.pro | 1 - .../corelib/thread/qatomicinteger/gcc/int/int.pro | 1 - .../thread/qatomicinteger/gcc/long/long.pro | 1 - .../qatomicinteger/gcc/qlonglong/qlonglong.pro | 1 - .../qatomicinteger/gcc/qptrdiff/qptrdiff.pro | 1 - .../qatomicinteger/gcc/quintptr/quintptr.pro | 1 - .../qatomicinteger/gcc/qulonglong/qulonglong.pro | 1 - .../thread/qatomicinteger/gcc/schar/schar.pro | 1 - .../thread/qatomicinteger/gcc/short/short.pro | 1 - .../thread/qatomicinteger/gcc/uchar/uchar.pro | 1 - .../thread/qatomicinteger/gcc/uint/uint.pro | 1 - .../thread/qatomicinteger/gcc/ulong/ulong.pro | 1 - .../thread/qatomicinteger/gcc/ushort/ushort.pro | 1 - .../thread/qatomicinteger/gcc/wchar_t/wchar_t.pro | 1 - .../thread/qatomicinteger/no-cxx11/char/char.pro | 1 - .../qatomicinteger/no-cxx11/char16_t/char16_t.pro | 1 - .../qatomicinteger/no-cxx11/char32_t/char32_t.pro | 1 - .../thread/qatomicinteger/no-cxx11/int/int.pro | 1 - .../thread/qatomicinteger/no-cxx11/long/long.pro | 1 - .../no-cxx11/qlonglong/qlonglong.pro | 1 - .../qatomicinteger/no-cxx11/qptrdiff/qptrdiff.pro | 1 - .../qatomicinteger/no-cxx11/quintptr/quintptr.pro | 1 - .../no-cxx11/qulonglong/qulonglong.pro | 1 - .../thread/qatomicinteger/no-cxx11/schar/schar.pro | 1 - .../thread/qatomicinteger/no-cxx11/short/short.pro | 1 - .../thread/qatomicinteger/no-cxx11/uchar/uchar.pro | 1 - .../thread/qatomicinteger/no-cxx11/uint/uint.pro | 1 - .../thread/qatomicinteger/no-cxx11/ulong/ulong.pro | 1 - .../qatomicinteger/no-cxx11/ushort/ushort.pro | 1 - .../qatomicinteger/no-cxx11/wchar_t/wchar_t.pro | 1 - .../thread/qatomicinteger/qatomicinteger.pri | 11 +- .../thread/qatomicinteger/qatomicinteger.pro | 40 - tests/auto/tools/moc/tst_moc.cpp | 2 +- 49 files changed, 5 insertions(+), 3685 deletions(-) delete mode 100644 src/corelib/arch/qatomic_armv5.h delete mode 100644 src/corelib/arch/qatomic_armv6.h delete mode 100644 src/corelib/arch/qatomic_armv7.h delete mode 100644 src/corelib/arch/qatomic_gcc.h delete mode 100644 src/corelib/arch/qatomic_ia64.h delete mode 100644 src/corelib/arch/qatomic_unix.cpp delete mode 100644 src/corelib/arch/qatomic_unix.h delete mode 100644 src/corelib/arch/qatomic_x86.h delete mode 100644 src/corelib/arch/sparc/arch.pri delete mode 100644 src/corelib/arch/sparc/qatomic32.s delete mode 100644 src/corelib/arch/sparc/qatomic64.s delete mode 100644 src/corelib/arch/sparc/qatomic_sparc.cpp delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/char/char.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/char16_t/char16_t.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/char32_t/char32_t.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/int/int.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/long/long.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/qlonglong/qlonglong.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/qptrdiff/qptrdiff.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/quintptr/quintptr.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/qulonglong/qulonglong.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/schar/schar.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/short/short.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/uchar/uchar.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/uint/uint.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/ulong/ulong.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/ushort/ushort.pro delete mode 100644 tests/auto/corelib/thread/qatomicinteger/no-cxx11/wchar_t/wchar_t.pro diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 083d912331..ec617386a4 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -1,19 +1,7 @@ win32|wince:HEADERS += arch/qatomic_msvc.h HEADERS += \ - arch/qatomic_armv5.h \ - arch/qatomic_armv6.h \ - arch/qatomic_armv7.h \ arch/qatomic_bootstrap.h \ - arch/qatomic_ia64.h \ - arch/qatomic_x86.h \ - arch/qatomic_gcc.h \ arch/qatomic_cxx11.h atomic64-libatomic: LIBS += -latomic - -unix { - # fallback implementation when no other appropriate qatomic_*.h exists - HEADERS += arch/qatomic_unix.h - SOURCES += arch/qatomic_unix.cpp -} diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h deleted file mode 100644 index bf34e76d83..0000000000 --- a/src/corelib/arch/qatomic_armv5.h +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2011 Thiago Macieira -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_ARMV5_H -#define QATOMIC_ARMV5_H - -#include - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT32_IS_SUPPORTED -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE - -#ifdef QT_NO_ARM_EABI -# error "Sorry, ARM without EABI is no longer supported" -#endif -#ifndef Q_OS_LINUX -# error "Qt is misconfigured: this ARMv5 implementation is only possible on Linux" -#endif - -template struct QBasicAtomicOps: QGenericAtomicOps > -{ - // kernel places a restartable cmpxchg implementation at a fixed address - template - static int _q_cmpxchg(T oldval, T newval, volatile T *ptr) Q_DECL_NOTHROW - { - typedef int (* kernel_cmpxchg_t)(T oldval, T newval, volatile T *ptr); - kernel_cmpxchg_t kernel_cmpxchg = *reinterpret_cast(0xffff0fc0); - return kernel_cmpxchg(oldval, newval, ptr); - } - static void _q_dmb() Q_DECL_NOTHROW - { - typedef void (* kernel_dmb_t)(); - kernel_dmb_t kernel_dmb = *reinterpret_cast(0xffff0fa0); - kernel_dmb(); - } - - template - static void orderedMemoryFence(const T &) Q_DECL_NOTHROW { _q_dmb(); } - - template static bool ref(T &_q_value) Q_DECL_NOTHROW; - template static bool deref(T &_q_value) Q_DECL_NOTHROW; - - static Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; } - static Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } - template static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; - template static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW; - template static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW; - template static - T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW; -}; - -template struct QAtomicOps : QBasicAtomicOps -{ - typedef T Type; -}; - -template<> template inline -bool QBasicAtomicOps<4>::ref(T &_q_value) Q_DECL_NOTHROW -{ - T originalValue; - T newValue; - do { - originalValue = _q_value; - newValue = originalValue + 1; - } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW -{ - T originalValue; - T newValue; - do { - originalValue = _q_value; - newValue = originalValue - 1; - } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - T originalValue; - do { - originalValue = _q_value; - if (originalValue != expectedValue) - return false; - } while (_q_cmpxchg(expectedValue, newValue, &_q_value) != 0); - return true; -} - -template<> template inline -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 (currentValue) - *currentValue = originalValue; - return false; - } - } while (_q_cmpxchg(expectedValue, newValue, &_q_value) != 0); - return true; -} - -// Fetch and store for integers -#ifdef Q_CC_RVCT -template<> template inline -__asm T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - add r2, pc, #0 - bx r2 - arm - swp r2,r1,[r0] - mov r0, r2 - bx lr - thumb -} -#else -template<> template inline -T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ -#if defined(__thumb__) - T originalValue; - do { - originalValue = _q_value; - } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); - return originalValue; -#else - T originalValue; - asm volatile("swp %0,%2,[%3]" - : "=&r"(originalValue), "=m" (_q_value) - : "r"(newValue), "r"(&_q_value) - : "cc", "memory"); - return originalValue; -#endif -} -#endif // Q_CC_RVCT - -template<> template inline -T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T originalValue; - T newValue; - do { - originalValue = _q_value; - newValue = originalValue + valueToAdd; - } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); - return originalValue; -} - -QT_END_NAMESPACE - -#endif // QATOMIC_ARMV5_H diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h deleted file mode 100644 index a72f41fdcb..0000000000 --- a/src/corelib/arch/qatomic_armv6.h +++ /dev/null @@ -1,839 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2011 Thiago Macieira -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_ARMV6_H -#define QATOMIC_ARMV6_H - -#include - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT32_IS_SUPPORTED -#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -template struct QBasicAtomicOps: QGenericAtomicOps > -{ - template - static void orderedMemoryFence(const T &) Q_DECL_NOTHROW; - - static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; } - template static bool ref(T &_q_value) Q_DECL_NOTHROW; - template 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 false; } - template static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; - template 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 static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW; - - static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return true; } - template static - T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW; - -private: - template static inline T shrinkFrom32Bit(T value); - template static inline T extendTo32Bit(T value); -}; - -template struct QAtomicOps : QBasicAtomicOps -{ - // this is GCC or GCC-like, so we can use extensions: - // force the alignment to be the size of the type, as on some ABIs the alignment - // of 64-bit types is 32-bit. We need proper alignment for LDREX / STREX. - typedef __attribute__((__aligned__(sizeof(T)))) T Type; -}; - -#ifndef Q_CC_RVCT - -#ifndef Q_DATA_MEMORY_BARRIER -# define Q_DATA_MEMORY_BARRIER asm volatile("mcr p15, 0, r0, c7, c10, 5":::"memory") -#endif -#ifndef Q_COMPILER_MEMORY_BARRIER -# define Q_COMPILER_MEMORY_BARRIER asm volatile("":::"memory") -#endif - -template<> template inline -bool QBasicAtomicOps<4>::ref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrex %[newValue], [%[_q_value]]\n" - "add %[newValue], %[newValue], #1\n" - "strex %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrex %[newValue], [%[_q_value]]\n" - "sub %[newValue], %[newValue], #1\n" - "strex %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - int result; - asm volatile("0:\n" - "ldrex %[result], [%[_q_value]]\n" - "eors %[result], %[result], %[expectedValue]\n" - "itt eq\n" - "strexeq %[result], %[newValue], [%[_q_value]]\n" - "teqeq %[result], #1\n" - "beq 0b\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return result == 0; -} - -template<> template inline -bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW -{ - T tempValue; - 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 inline -T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T originalValue; - int result; - asm volatile("0:\n" - "ldrex %[originalValue], [%[_q_value]]\n" - "strex %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [result] "=&r" (result), - "+m" (_q_value) - : [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return originalValue; -} - -template<> template inline -T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T originalValue; - T newValue; - int result; - asm volatile("0:\n" - "ldrex %[originalValue], [%[_q_value]]\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - "strex %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType::AddScale), - [_q_value] "r" (&_q_value) - : "cc"); - return originalValue; -} - -#if defined(__ARM_ARCH_7__) \ - || defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) \ - || defined(__ARM_ARCH_7M__) \ - || defined(__ARM_ARCH_6K__) -// LDREXB, LDREXH and LDREXD are available on ARMv6K or higher - -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 -#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT16_IS_SUPPORTED -#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT64_IS_SUPPORTED -#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -// note: if T is signed, parameters are passed sign-extended in the -// registers. However, our 8- and 16-bit operations don't do sign -// extension. So we need to clear out the input on entry and sign-extend again -// on exit. -template template -T QBasicAtomicOps::shrinkFrom32Bit(T value) -{ - Q_STATIC_ASSERT(Size == 1 || Size == 2); - if (T(-1) > T(0)) - return value; // unsigned, ABI will zero extend - if (Size == 1) - asm volatile("and %0, %0, %1" : "+r" (value) : "I" (0xff)); - else - asm volatile("and %0, %0, %1" : "+r" (value) : "r" (0xffff)); - return value; -} - -template template -T QBasicAtomicOps::extendTo32Bit(T value) -{ - Q_STATIC_ASSERT(Size == 1 || Size == 2); - if (T(-1) > T(0)) - return value; // unsigned, ABI will zero extend - if (Size == 1) - asm volatile("sxtb %0, %0" : "+r" (value)); - else - asm volatile("sxth %0, %0" : "+r" (value)); - return value; -} - -template<> template inline -bool QBasicAtomicOps<1>::ref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrexb %[newValue], [%[_q_value]]\n" - "add %[newValue], %[newValue], #1\n" - "strexb %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<1>::deref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrexb %[newValue], [%[_q_value]]\n" - "sub %[newValue], %[newValue], #1\n" - "strexb %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - T result; - asm volatile("0:\n" - "ldrexb %[result], [%[_q_value]]\n" - "eors %[result], %[result], %[expectedValue]\n" - "itt eq\n" - "strexbeq %[result], %[newValue], [%[_q_value]]\n" - "teqeq %[result], #1\n" - "beq 0b\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [expectedValue] "r" (shrinkFrom32Bit(expectedValue)), - [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return result == 0; -} - -template<> template inline -bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW -{ - T tempValue; - 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" (shrinkFrom32Bit(expectedValue)), - [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - *currentValue = extendTo32Bit(tempValue); - return result == 0; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T originalValue; - int result; - asm volatile("0:\n" - "ldrexb %[originalValue], [%[_q_value]]\n" - "strexb %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [result] "=&r" (result), - "+m" (_q_value) - : [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return extendTo32Bit(originalValue); -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T originalValue; - T newValue; - int result; - asm volatile("0:\n" - "ldrexb %[originalValue], [%[_q_value]]\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - "strexb %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType::AddScale), - [_q_value] "r" (&_q_value) - : "cc"); - return extendTo32Bit(originalValue); -} - -template<> template inline -bool QBasicAtomicOps<2>::ref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrexh %[newValue], [%[_q_value]]\n" - "add %[newValue], %[newValue], #1\n" - "strexh %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<2>::deref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrexh %[newValue], [%[_q_value]]\n" - "sub %[newValue], %[newValue], #1\n" - "strexh %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - T result; - asm volatile("0:\n" - "ldrexh %[result], [%[_q_value]]\n" - "eors %[result], %[result], %[expectedValue]\n" - "itt eq\n" - "strexheq %[result], %[newValue], [%[_q_value]]\n" - "teqeq %[result], #1\n" - "beq 0b\n" - : [result] "=&r" (result), - "+m" (_q_value) - : [expectedValue] "r" (shrinkFrom32Bit(expectedValue)), - [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return result == 0; -} - -template<> template inline -bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW -{ - T tempValue; - 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" (shrinkFrom32Bit(expectedValue)), - [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - *currentValue = extendTo32Bit(tempValue); - return result == 0; -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T originalValue; - int result; - asm volatile("0:\n" - "ldrexh %[originalValue], [%[_q_value]]\n" - "strexh %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [result] "=&r" (result), - "+m" (_q_value) - : [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return extendTo32Bit(originalValue); -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T originalValue; - T newValue; - int result; - asm volatile("0:\n" - "ldrexh %[originalValue], [%[_q_value]]\n" - "add %[newValue], %[originalValue], %[valueToAdd]\n" - "strexh %[result], %[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType::AddScale), - [_q_value] "r" (&_q_value) - : "cc"); - return extendTo32Bit(originalValue); -} - -// Explanation from GCC's source code (config/arm/arm.c) on the modifiers below: -// Whenever you use "r" (dwordVariable), you get assigned a register pair: -// %[reg] - lower-numbered register -// %H[reg] - higher-numbered register -// %Q[reg] - low part of the value -// %R[reg] - high part of the value -// If this is a little-endian build, H and R are the same; otherwise, H and Q are the same. - -template<> template inline -bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrexd %[newValue], %H[newValue], [%[_q_value]]\n" - "adds %Q[newValue], %Q[newValue], #1\n" - "adc %R[newValue], %R[newValue], #0\n" - "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW -{ - T newValue; - int result; - asm volatile("0:\n" - "ldrexd %[newValue], %H[newValue], [%[_q_value]]\n" - "subs %Q[newValue], %Q[newValue], #1\n" - "sbc %R[newValue], %R[newValue], #0\n" - "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [_q_value] "r" (&_q_value) - : "cc", "memory"); - return newValue != 0; -} - -template<> template inline -bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - T result; - asm volatile("0:\n" - "ldrexd %[result], %H[result], [%[_q_value]]\n" - "eor %[result], %[result], %[expectedValue]\n" - "eor %H[result], %H[result], %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), - "+m" (_q_value) - : [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return quint32(result) == 0; -} - -template<> template inline -bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW -{ - T tempValue; - 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 inline -T QBasicAtomicOps<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T originalValue; - int result; - asm volatile("0:\n" - "ldrexd %[originalValue], %H[originalValue], [%[_q_value]]\n" - "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [result] "=&r" (result), - "+m" (_q_value) - : [newValue] "r" (newValue), - [_q_value] "r" (&_q_value) - : "cc"); - return originalValue; -} - -template<> template inline -T QBasicAtomicOps<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T originalValue; - T newValue; - int result; - asm volatile("0:\n" - "ldrexd %[originalValue], %H[originalValue], [%[_q_value]]\n" - "adds %Q[newValue], %Q[originalValue], %Q[valueToAdd]\n" - "adc %R[newValue], %R[originalValue], %R[valueToAdd]\n" - "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" - "teq %[result], #0\n" - "bne 0b\n" - : [originalValue] "=&r" (originalValue), - [newValue] "=&r" (newValue), - [result] "=&r" (result), - "+m" (_q_value) - : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType::AddScale), - [_q_value] "r" (&_q_value) - : "cc"); - return originalValue; -} - -#endif - -#else -// This is Q_CC_RVCT - -// RVCT inline assembly documentation: -// http://www.keil.com/support/man/docs/armcc/armcc_chdcffdb.htm -// RVCT embedded assembly documentation: -// http://www.keil.com/support/man/docs/armcc/armcc_chddbeib.htm - -#if __TARGET_ARCH_THUMB-0 < 4 -// save our pragma state and switch to ARM mode (unless using Thumb2) -# pragma push -# pragma arm -#endif - -#ifndef Q_DATA_MEMORY_BARRIER -# define Q_DATA_MEMORY_BARRIER __schedule_barrier() -#endif -#ifndef Q_COMPILER_MEMORY_BARRIER -# define Q_COMPILER_MEMORY_BARRIER __schedule_barrier() -#endif - -inline bool QBasicAtomicInt::ref() Q_DECL_NOTHROW -{ - int newValue; - int result; - retry: - __asm { - ldrex newValue, [&_q_value] - add newValue, newValue, #1 - strex result, newValue, [&_q_value] - teq result, #0 - bne retry - } - return newValue != 0; -} - -inline bool QBasicAtomicInt::deref() Q_DECL_NOTHROW -{ - int newValue; - int result; - retry: - __asm { - ldrex newValue, [&_q_value] - sub newValue, newValue, #1 - strex result, newValue, [&_q_value] - teq result, #0 - bne retry - } - return newValue != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) Q_DECL_NOTHROW -{ - int result; - retry: - __asm { - ldrex result, [&_q_value] - eors result, result, expectedValue - strexeq result, newValue, [&_q_value] - teqeq result, #1 - beq retry - } - return result == 0; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) Q_DECL_NOTHROW -{ - int originalValue; - int result; - retry: - __asm { - ldrex originalValue, [&_q_value] - strex result, newValue, [&_q_value] - teq result, #0 - bne retry - } - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) Q_DECL_NOTHROW -{ - int originalValue; - int newValue; - int result; - retry: - __asm { - ldrex originalValue, [&_q_value] - add newValue, originalValue, valueToAdd - strex result, newValue, [&_q_value] - teq result, #0 - bne retry - } - return originalValue; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) Q_DECL_NOTHROW -{ - T *result; - retry: - __asm { - ldrex result, [&_q_value] - eors result, result, expectedValue - strexeq result, newValue, [&_q_value] - teqeq result, #1 - beq retry - } - return result == 0; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) Q_DECL_NOTHROW -{ - T *originalValue; - int result; - retry: - __asm { - ldrex originalValue, [&_q_value] - strex result, newValue, [&_q_value] - teq result, #0 - bne retry - } - return originalValue; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) Q_DECL_NOTHROW -{ - T *originalValue; - T *newValue; - int result; - retry: - __asm { - ldrex originalValue, [&_q_value] - add newValue, originalValue, valueToAdd * sizeof(T) - strex result, newValue, [&_q_value] - teq result, #0 - bne retry - } - return originalValue; -} - -#if __TARGET_ARCH_THUMB-0 < 4 -# pragma pop -#endif - -#endif - -// common code - -template template inline -void QBasicAtomicOps::orderedMemoryFence(const T &) Q_DECL_NOTHROW -{ - Q_DATA_MEMORY_BARRIER; -} - -#undef Q_DATA_MEMORY_BARRIER -#undef Q_COMPILER_MEMORY_BARRIER - -QT_END_NAMESPACE - -#endif // QATOMIC_ARMV6_H diff --git a/src/corelib/arch/qatomic_armv7.h b/src/corelib/arch/qatomic_armv7.h deleted file mode 100644 index 4ea0551c82..0000000000 --- a/src/corelib/arch/qatomic_armv7.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_ARMV7_H -#define QATOMIC_ARMV7_H - -// use the DMB instruction when compiling for ARMv7, ... -#ifndef Q_CC_RCVT -# define Q_DATA_MEMORY_BARRIER asm volatile("dmb\n":::"memory") -#else -# define Q_DATA_MEMORY_BARRIER do{__asm { dmb } __schedule_barrier();}while(0) -#endif - -// ... but the implementation is otherwise identical to that for ARMv6 -#include "QtCore/qatomic_armv6.h" - -#if 0 -// silence syncqt warnings -QT_BEGIN_NAMESPACE - -QT_END_NAMESPACE - -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#endif // QATOMIC_ARMV7_H diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h deleted file mode 100644 index 4c8b7297d9..0000000000 --- a/src/corelib/arch/qatomic_gcc.h +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Thiago Macieira -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_GCC_H -#define QATOMIC_GCC_H - -#include - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#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 -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE - -#define Q_ATOMIC_INT32_IS_SUPPORTED -#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE - -#define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE - -#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 struct QAtomicOps: QGenericAtomicOps > -{ - // The GCC intrinsics all have fully-ordered memory semantics, so we define - // only the xxxRelaxed functions. The exception is __sync_lock_and_test, - // which has acquire semantics, so we need to define the Release and - // Ordered versions too. - - typedef X Type; - -#ifndef __ia64__ - template - static T loadAcquire(const T &_q_value) Q_DECL_NOTHROW - { - T tmp = _q_value; - __sync_synchronize(); - return tmp; - } - - template - static void storeRelease(T &_q_value, T newValue) Q_DECL_NOTHROW - { - __sync_synchronize(); - _q_value = newValue; - } -#endif - - static Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; } - static Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } - template - static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW - { - return __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue); - } - - template - 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 - static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW - { - return __sync_lock_test_and_set(&_q_value, newValue); - } - - template - static T fetchAndStoreRelease(T &_q_value, T newValue) Q_DECL_NOTHROW - { - __sync_synchronize(); - return __sync_lock_test_and_set(&_q_value, newValue); - } - - template - static T fetchAndStoreOrdered(T &_q_value, T newValue) Q_DECL_NOTHROW - { - return fetchAndStoreRelease(_q_value, newValue); - } - - template static - T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW - { - return __sync_fetch_and_add(&_q_value, valueToAdd * QAtomicAdditiveType::AddScale); - } -}; - -QT_END_NAMESPACE -#endif // QATOMIC_GCC_H diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h deleted file mode 100644 index 1957dca87a..0000000000 --- a/src/corelib/arch/qatomic_ia64.h +++ /dev/null @@ -1,1090 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2011 Thiago Macieira -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_IA64_H -#define QATOMIC_IA64_H - -#include - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT32_IS_SUPPORTED - -#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE - -#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT8_IS_SUPPORTED - -#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT16_IS_SUPPORTED - -#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -#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 - -#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -#define Q_ATOMIC_INT64_IS_SUPPORTED - -#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_WAIT_FREE - -#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 - -template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; }; -template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; }; -template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; }; - -template struct QBasicAtomicOps: QGenericAtomicOps > -{ - template - static void orderedMemoryFence(const T &) Q_DECL_NOTHROW; - - template static inline - T loadAcquire(const T &_q_value) Q_DECL_NOTHROW - { - return *static_cast(&_q_value); - } - - template static inline - void storeRelease(T &_q_value, T newValue) Q_DECL_NOTHROW - { - *static_cast(&_q_value) = newValue; - } - static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; } - static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return size == 4 || size == 8; } - template static bool ref(T &_q_value) Q_DECL_NOTHROW; - template 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; } - template static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; - template static bool testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; - template static bool testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW; - template 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; } - template static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW; - template static T fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW; - template static T fetchAndStoreRelease(T &_q_value, T newValue) Q_DECL_NOTHROW; - template static T fetchAndStoreOrdered(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 false; } - template static - T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW; - template static - T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW; - template static - T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW; - template static - T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW; -}; - -template struct QAtomicOps : QBasicAtomicOps -{ - typedef T Type; -}; - -inline bool _q_ia64_fetchadd_immediate(int value) -{ - return value == 1 || value == -1 - || value == 4 || value == -4 - || value == 8 || value == -8 - || value == 16 || value == -16; -} - -#if defined(Q_CC_INTEL) - -// intrinsics provided by the Intel C++ Compiler -#include - -template template inline -void QBasicAtomicOps::orderedMemoryFence(const T &) -{ - __memory_barrier(); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return static_cast(_InterlockedExchange(&_q_value, newValue)); -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - int expectedValueCopy = expectedValue; - return (static_cast(_InterlockedCompareExchange(&_q_value, - newValue, - expectedValueCopy)) - == expectedValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - int expectedValueCopy = expectedValue; - return (static_cast(_InterlockedCompareExchange_acq(reinterpret_cast(&_q_value), - newValue, - expectedValueCopy)) - == expectedValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - int expectedValueCopy = expectedValue; - return (static_cast(_InterlockedCompareExchange_rel(reinterpret_cast(&_q_value), - newValue, - expectedValueCopy)) - == expectedValue); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - if (__builtin_constant_p(valueToAdd)) { - if (valueToAdd == 1) - return __fetchadd4_acq((unsigned int *)&_q_value, 1); - if (valueToAdd == -1) - return __fetchadd4_acq((unsigned int *)&_q_value, -1); - } - return _InterlockedExchangeAdd(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - if (__builtin_constant_p(valueToAdd)) { - if (valueToAdd == 1) - return __fetchadd4_rel((unsigned int *)&_q_value, 1); - if (valueToAdd == -1) - return __fetchadd4_rel((unsigned int *)&_q_value, -1); - } - __memory_barrier(); - return _InterlockedExchangeAdd(&_q_value, valueToAdd); -} - -inline bool QBasicAtomicInt::ref() -{ - return _InterlockedIncrement(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - return _InterlockedDecrement(&_q_value) != 0; -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return (T *)_InterlockedExchangePointer(reinterpret_cast(&_q_value), newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - T *expectedValueCopy = expectedValue; - return (_InterlockedCompareExchangePointer(reinterpret_cast(&_q_value), - newValue, - expectedValueCopy) - == expectedValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - union { - volatile void *x; - volatile unsigned long *p; - }; - x = &_q_value; - T *expectedValueCopy = expectedValue; - return (_InterlockedCompareExchange64_acq(p, quintptr(newValue), quintptr(expectedValueCopy)) - == quintptr(expectedValue)); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - union { - volatile void *x; - volatile unsigned long *p; - }; - x = &_q_value; - T *expectedValueCopy = expectedValue; - return (_InterlockedCompareExchange64_rel(p, quintptr(newValue), quintptr(expectedValueCopy)) - == quintptr(expectedValue)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return (T *)_InterlockedExchangeAdd64((volatile long *)&_q_value, - valueToAdd * sizeof(T)); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) -{ - __memory_barrier(); - return (T *)_InterlockedExchangeAdd64((volatile long *)&_q_value, - valueToAdd * sizeof(T)); -} - -#elif defined(Q_CC_GNU) - -template template inline -void QBasicAtomicOps::orderedMemoryFence(const T &) Q_DECL_NOTHROW -{ - asm volatile("mf" ::: "memory"); -} - -template<> template inline -bool QBasicAtomicOps<4>::ref(T &_q_value) Q_DECL_NOTHROW -{ - T ret; - asm volatile("fetchadd4.acq %0=%1,1\n" - : "=r" (ret), "+m" (_q_value) - : - : "memory"); - return ret != -1; -} - -template<> template inline -bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW -{ - T ret; - asm volatile("fetchadd4.rel %0=%1,-1\n" - : "=r" (ret), "+m" (_q_value) - : - : "memory"); - return ret != 1; -} - -template<> template inline -bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW -{ - T ret; - asm volatile("fetchadd8.acq %0=%1,1\n" - : "=r" (ret), "+m" (_q_value) - : - : "memory"); - return ret != -1; -} - -template<> template inline -bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW -{ - T ret; - asm volatile("fetchadd8.rel %0=%1,-1\n" - : "=r" (ret), "+m" (_q_value) - : - : "memory"); - return ret != 1; -} - -template<> template inline -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" - ";;\n" - "cmpxchg1.acq %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -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" - ";;\n" - "cmpxchg1.rel %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -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" - ";;\n" - "cmpxchg2.acq %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -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" - ";;\n" - "cmpxchg2.rel %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -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" - ";;\n" - "cmpxchg4.acq %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -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" - ";;\n" - "cmpxchg4.rel %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -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" - ";;\n" - "cmpxchg8.acq %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -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" - ";;\n" - "cmpxchg8.rel %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - if (currentValue) - *currentValue = ret; - return ret == expectedValue; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T ret; - asm volatile("xchg1 %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T ret; - asm volatile("xchg2 %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<4>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T ret; - asm volatile("xchg4 %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<8>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - T ret; - asm volatile("xchg8 %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg1.acq %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg1.rel %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg2.acq %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg2.rel %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<4>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - -#if (__GNUC__ >= 4) - // We implement a fast fetch-and-add when we can - if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) { - asm volatile("fetchadd4.acq %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "i" (valueToAdd) - : "memory"); - return ret; - } -#endif - - // otherwise, use a loop around test-and-set - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg4.acq %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<4>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - -#if (__GNUC__ >= 4) - // We implement a fast fetch-and-add when we can - if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) { - asm volatile("fetchadd4.rel %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "i" (valueToAdd) - : "memory"); - return ret; - } -#endif - - // otherwise, use a loop around test-and-set - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg4.rel %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<8>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - -#if (__GNUC__ >= 4) - // We implement a fast fetch-and-add when we can - if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) { - asm volatile("fetchadd8.acq %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "i" (valueToAdd) - : "memory"); - return ret; - } -#endif - - // otherwise, use a loop around test-and-set - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg8.acq %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -template<> template inline -T QBasicAtomicOps<8>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T ret; - valueToAdd *= QAtomicAdditiveType::AddScale; - -#if (__GNUC__ >= 4) - // We implement a fast fetch-and-add when we can - if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) { - asm volatile("fetchadd8.rel %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "i" (valueToAdd) - : "memory"); - return ret; - } -#endif - - // otherwise, use a loop around test-and-set - ret = _q_value; - asm volatile("0:\n" - " mov r9=%0\n" - " mov ar.ccv=%0\n" - " add %0=%0, %2\n" - " ;;\n" - " cmpxchg8.rel %0=%1,%0,ar.ccv\n" - " ;;\n" - " cmp.ne p6,p0 = %0, r9\n" - "(p6) br.dptk 0b\n" - "1:\n" - : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd) - : "r9", "p6", "memory"); - return ret; -} - -#elif defined Q_CC_HPACC - -QT_BEGIN_INCLUDE_NAMESPACE -#include -QT_END_INCLUDE_NAMESPACE - -#define FENCE (_Asm_fence)(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE) - -template inline -void QBasicAtomicOps::orderedMemoryFence() Q_DECL_NOTHROW -{ - _Asm_mf(FENCE); -} - -template<> template inline -bool QBasicAtomicOps<4>::ref(T &_q_value) Q_DECL_NOTHROW -{ - return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != -1; -} - -template<> template inline -bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW -{ - return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL, - &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != 1; -} - -template<> template inline -bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW -{ - return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_D, (_Asm_sem)_SEM_ACQ, - &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != -1; -} - -template<> template inline -bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW -{ - return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_D, (_Asm_sem)_SEM_REL, - &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != 1; -} - -template<> template inline -bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_ACQ, - &_q_value, (quint8)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_REL, - &_q_value, (quint8)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_ACQ, - &_q_value, (quint16)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_REL, - &_q_value, (quint16)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, (unsigned)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, - &_q_value, newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ, - &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW -{ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE); - T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL, - &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - return (T)_Asm_xchg((_Asm_sz)_SZ_B, &_q_value, (quint8)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - return (T)_Asm_xchg((_Asm_sz)_SZ_H, &_q_value, (quint16)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); -} - -template<> template inline -T QBasicAtomicOps<4>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - return (T)_Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); -} - -template<> template inline -T QBasicAtomicOps<8>::fetchAndStoreAcquire(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - return (T)_Asm_xchg((_Asm_sz)_SZ_D, &_q_value, (quint64)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - valueToAdd *= QAtomicAdditiveType::AddScale; - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_ACQ, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_REL, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - valueToAdd *= QAtomicAdditiveType::AddScale; - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_ACQ, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -template<> template inline -T QBasicAtomicOps<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_REL, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -template<> template inline -T QBasicAtomicOps<4>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - valueToAdd *= QAtomicAdditiveType::AddScale; - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -template<> template inline -T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -template<> template inline -T QBasicAtomicOps<8>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - valueToAdd *= QAtomicAdditiveType::AddScale; - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -template<> template inline -T QBasicAtomicOps<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - // implement the test-and-set loop - T old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; -} - -#endif - -template template inline -bool QBasicAtomicOps::ref(T &_q_value) Q_DECL_NOTHROW -{ - // no fetchadd for 1 or 2 bytes - return fetchAndAddRelaxed(_q_value, 1) == -1; -} - -template template inline -bool QBasicAtomicOps::deref(T &_q_value) Q_DECL_NOTHROW -{ - // no fetchadd for 1 or 2 bytes - return fetchAndAddRelaxed(_q_value, -1) == 1; -} - -template template inline -bool QBasicAtomicOps::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW -{ - return testAndSetAcquire(_q_value, expectedValue, newValue, currentValue); -} - -template template inline -bool QBasicAtomicOps::testAndSetOrdered(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW -{ - orderedMemoryFence(_q_value); - return testAndSetAcquire(_q_value, expectedValue, newValue, currentValue); -} - -template template inline -T QBasicAtomicOps::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - return fetchAndStoreAcquire(_q_value, newValue); -} - -template template inline -T QBasicAtomicOps::fetchAndStoreRelease(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - orderedMemoryFence(_q_value); - return fetchAndStoreAcquire(_q_value, newValue); -} - -template template inline -T QBasicAtomicOps::fetchAndStoreOrdered(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - return fetchAndStoreRelease(_q_value, newValue); -} - -template template inline -T QBasicAtomicOps::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - return fetchAndAddAcquire(_q_value, valueToAdd); -} - -template template inline -T QBasicAtomicOps::fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - orderedMemoryFence(_q_value); - return fetchAndAddRelease(_q_value, valueToAdd); -} - -QT_END_NAMESPACE - -#endif // QATOMIC_IA64_H diff --git a/src/corelib/arch/qatomic_unix.cpp b/src/corelib/arch/qatomic_unix.cpp deleted file mode 100644 index 0a545197dd..0000000000 --- a/src/corelib/arch/qatomic_unix.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformdefs.h" - -#include - -// If operating system, processor, and compiler detection fails, we fall back -// to this generic, out-of-line implementation - -#if defined(QATOMIC_UNIX_H) - -QT_BEGIN_NAMESPACE -static pthread_mutex_t qAtomicMutex = PTHREAD_MUTEX_INITIALIZER; - -Q_CORE_EXPORT -bool QAtomicOps::testAndSetRelaxed(int &_q_value, int expectedValue, int 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::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::testAndSetRelaxed(void *&_q_value, void *expectedValue, void *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; -} - -QT_END_NAMESPACE - -#endif // QATOMIC_UNIX_H diff --git a/src/corelib/arch/qatomic_unix.h b/src/corelib/arch/qatomic_unix.h deleted file mode 100644 index e686b3d00e..0000000000 --- a/src/corelib/arch/qatomic_unix.h +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_UNIX_H -#define QATOMIC_UNIX_H - -#include - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE -#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 - -// No definition, needs specialization -template struct QAtomicOps; - -// 32-bit version -template <> -struct QAtomicOps : QGenericAtomicOps > -{ - typedef int 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(int &_q_value, int expectedValue, int newValue) Q_DECL_NOTHROW; -}; - -// 64-bit version -template <> -struct QAtomicOps : QGenericAtomicOps > -{ - 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 : QGenericAtomicOps > -{ - typedef void *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(void *&_q_value, void *expectedValue, void *newValue) Q_DECL_NOTHROW; -}; - -template -struct QAtomicOps : QGenericAtomicOps > -{ - typedef T *Type; - - // helper to strip cv qualifiers - static inline void *nocv(const T *p) { return const_cast(static_cast(p)); } - - static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; } - static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; } - static inline bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) Q_DECL_NOTHROW - { - // forward to the void* specialization - void *voidp = nocv(_q_value); - bool returnValue = QAtomicOps::testAndSetRelaxed(voidp, nocv(expectedValue), nocv(newValue)); - _q_value = reinterpret_cast(voidp); - return returnValue; - } -}; - -// 32- and 64-bit unsigned versions -template <> struct QAtomicOps : QAtomicOps -{ - typedef unsigned Type; - Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW - { - return QAtomicOps::testAndSetRelaxed(reinterpret_cast(_q_value), int(expectedValue), int(newValue)); - } -}; -template <> struct QAtomicOps : QAtomicOps -{ - typedef unsigned long longType; - Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW - { - return QAtomicOps::testAndSetRelaxed(reinterpret_cast(_q_value), int(expectedValue), int(newValue)); - } -}; - -QT_END_NAMESPACE -#endif // QATOMIC_UNIX_H diff --git a/src/corelib/arch/qatomic_x86.h b/src/corelib/arch/qatomic_x86.h deleted file mode 100644 index 2d2500fd17..0000000000 --- a/src/corelib/arch/qatomic_x86.h +++ /dev/null @@ -1,439 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2011 Thiago Macieira -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QATOMIC_X86_H -#define QATOMIC_X86_H - -#include - -QT_BEGIN_NAMESPACE - -#if 0 -// silence syncqt warnings -QT_END_NAMESPACE -#pragma qt_sync_skip_header_check -#pragma qt_sync_stop_processing -#endif - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE - -#define Q_ATOMIC_INT32_IS_SUPPORTED - -#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE - -#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_WAIT_FREE - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE - -template struct QBasicAtomicOps: QGenericAtomicOps > -{ - static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; } - static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return true; } - template static bool ref(T &_q_value) Q_DECL_NOTHROW; - template 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; } - template static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW; - template 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; } - template 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; } - template static - T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW; -}; - -template struct QAtomicOps : QBasicAtomicOps -{ - typedef T Type; -}; - -#if defined(Q_CC_GNU) - -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: - * - * x86 instructions are in the form "{opcode}{length} {source}, {destination}", - * where the length is one of the letters "b" (byte), "w" (word, 16-bit), "l" - * (dword, 32-bit), "q" (qword, 64-bit). - * - * In most cases, we can omit the length because it's inferred from one of the - * registers. For example, "xchg %0,%1" doesn't need the length suffix because - * we can only exchange data of the same size and one of the operands must be a - * register. - * - * The exception is the increment and decrement functions, where we add and - * subtract an immediate value (1). For those, we need to specify the length. - * GCC and ICC support the syntax "add%z0 $1, %0", where "%z0" expands to the - * length of the operand. Unfortunately, clang as of 3.0 doesn't support that. - * For that reason, the ref() and deref() functions are rolled out for all - * sizes. - * - * The functions are also rolled out for the 1-byte operations since those - * require a special register constraint "q" to force the compiler to schedule - * one of the 8-bit registers. It's probably a compiler bug that it tries to - * use a register that doesn't exist. - * - * Finally, 64-bit operations are supported via the cmpxchg8b instruction on - * 32-bit processors, via specialisation below. - */ - -template<> template inline -bool QBasicAtomicOps<1>::ref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "addb $1, %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} - -template<> template inline -bool QBasicAtomicOps<2>::ref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "incw %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} - -template<> template inline -bool QBasicAtomicOps<4>::ref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "addl $1, %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} - -template<> template inline -bool QBasicAtomicOps<1>::deref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "subb $1, %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} - -template<> template inline -bool QBasicAtomicOps<2>::deref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "decw %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} -template<> template inline -bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "subl $1, %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} - -template template inline -bool QBasicAtomicOps::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) 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"); - return ret != 0; -} - -template<> template inline -bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) 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"); - return ret != 0; -} - -template template inline -bool QBasicAtomicOps::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 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 template inline -T QBasicAtomicOps::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - asm volatile("xchg %0,%1" - : "=r" (newValue), "+m" (_q_value) - : "0" (newValue) - : "memory"); - return newValue; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW -{ - asm volatile("xchg %0,%1" - : "=q" (newValue), "+m" (_q_value) - : "0" (newValue) - : "memory"); - return newValue; -} - -template template inline -T QBasicAtomicOps::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T result; - asm volatile("lock\n" - "xadd %0,%1" - : "=r" (result), "+m" (_q_value) - : "0" (T(valueToAdd * QAtomicAdditiveType::AddScale)) - : "memory"); - return result; -} - -template<> template inline -T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType::AdditiveT valueToAdd) Q_DECL_NOTHROW -{ - T result; - asm volatile("lock\n" - "xadd %0,%1" - : "=q" (result), "+m" (_q_value) - : "0" (T(valueToAdd * QAtomicAdditiveType::AddScale)) - : "memory"); - return result; -} - -#define Q_ATOMIC_INT8_IS_SUPPORTED - -#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_WAIT_FREE - -#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_TEST_AND_SET_IS_WAIT_FREE - -#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_WAIT_FREE - -#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_WAIT_FREE - -#define 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 - -#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 -#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_WAIT_FREE - -#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 - -// native support for 64-bit types -template<> template inline -bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "addq $1, %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} - -template<> template inline -bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW -{ - unsigned char ret; - asm volatile("lock\n" - "subq $1, %0\n" - "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) - : "memory"); - return ret != 0; -} -#else -// i386 architecture, emulate 64-bit support via cmpxchg8b -template <> struct QBasicAtomicOps<8>: QGenericAtomicOps > -{ - 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 static inline - bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW - { -#ifdef __PIC__ -# define EBX_reg "r" -# define EBX_load(reg) "xchg " reg ", %%ebx\n" -#else -# define EBX_reg "b" -# define EBX_load(reg) -#endif - quint32 highExpectedValue = quint32(newValue >> 32); // ECX - asm volatile(EBX_load("%3") - "lock\n" - "cmpxchg8b %0\n" - EBX_load("%3") - "sete %%cl\n" - : "+m" (_q_value), "+c" (highExpectedValue), "+&A" (expectedValue) - : EBX_reg (quint32(newValue & 0xffffffff)) - : "memory"); - // if the comparison failed, expectedValue here contains the current value - return quint8(highExpectedValue) != 0; -#undef EBX_reg -#undef EBX_load - } -}; -#endif - -#else -# error "This compiler for x86 is not supported" -#endif - - -QT_END_NAMESPACE - -#endif // QATOMIC_X86_H diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri deleted file mode 100644 index a201c83c6a..0000000000 --- a/src/corelib/arch/sparc/arch.pri +++ /dev/null @@ -1,10 +0,0 @@ -# -# SPARC architecture -# -*-64* { - SOURCES += $$PWD/qatomic64.s -} -else { - SOURCES += $$PWD/qatomic32.s \ - $$PWD/qatomic_sparc.cpp -} diff --git a/src/corelib/arch/sparc/qatomic32.s b/src/corelib/arch/sparc/qatomic32.s deleted file mode 100644 index 0105439969..0000000000 --- a/src/corelib/arch/sparc/qatomic32.s +++ /dev/null @@ -1,101 +0,0 @@ -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! -!! Copyright (C) 2016 The Qt Company Ltd. -!! Contact: https://www.qt.io/licensing/ -!! -!! 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 The Qt Company. For licensing terms -!! and conditions see https://www.qt.io/terms-conditions. For further -!! information use the contact form at https://www.qt.io/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 3 as published by the Free Software -!! Foundation and appearing in the file LICENSE.LGPL3 included in the -!! packaging of this file. Please review the following information to -!! ensure the GNU Lesser General Public License version 3 requirements -!! will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -!! -!! GNU General Public License Usage -!! Alternatively, this file may be used under the terms of the GNU -!! General Public License version 2.0 or (at your option) the GNU General -!! Public license version 3 or any later version approved by the KDE Free -!! Qt Foundation. The licenses are as published by the Free Software -!! Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -!! included in the packaging of this file. Please review the following -!! information to ensure the GNU General Public License requirements will -!! be met: https://www.gnu.org/licenses/gpl-2.0.html and -!! https://www.gnu.org/licenses/gpl-3.0.html. -!! -!! $QT_END_LICENSE$ -!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - .section ".text" - - .align 4 - .type q_atomic_trylock_int,#function - .global q_atomic_trylock_int -q_atomic_trylock_int: - sethi %hi(-2147483648),%o2 - swap [%o0],%o2 - retl - mov %o2,%o0 - .size q_atomic_trylock_int,.-q_atomic_trylock_int - - - - - .align 4 - .type q_atomic_trylock_ptr,#function - .global q_atomic_trylock_ptr -q_atomic_trylock_ptr: - mov -1, %o2 - swap [%o0], %o2 - retl - mov %o2, %o0 - .size q_atomic_trylock_ptr,.-q_atomic_trylock_ptr - - - - - .align 4 - .type q_atomic_unlock,#function - .global q_atomic_unlock -q_atomic_unlock: - stbar - retl - st %o1,[%o0] - .size q_atomic_unlock,.-q_atomic_unlock - - - - - .align 4 - .type q_atomic_set_int,#function - .global q_atomic_set_int -q_atomic_set_int: - swap [%o0],%o1 - stbar - retl - mov %o1,%o0 - .size q_atomic_set_int,.-q_atomic_set_int - - - - - .align 4 - .type q_atomic_set_ptr,#function - .global q_atomic_set_ptr -q_atomic_set_ptr: - swap [%o0],%o1 - stbar - retl - mov %o1,%o0 - .size q_atomic_set_ptr,.-q_atomic_set_ptr - diff --git a/src/corelib/arch/sparc/qatomic64.s b/src/corelib/arch/sparc/qatomic64.s deleted file mode 100644 index ae5c57a173..0000000000 --- a/src/corelib/arch/sparc/qatomic64.s +++ /dev/null @@ -1,325 +0,0 @@ -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! -!! Copyright (C) 2016 The Qt Company Ltd. -!! Contact: https://www.qt.io/licensing/ -!! -!! 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 The Qt Company. For licensing terms -!! and conditions see https://www.qt.io/terms-conditions. For further -!! information use the contact form at https://www.qt.io/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 3 as published by the Free Software -!! Foundation and appearing in the file LICENSE.LGPL3 included in the -!! packaging of this file. Please review the following information to -!! ensure the GNU Lesser General Public License version 3 requirements -!! will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -!! -!! GNU General Public License Usage -!! Alternatively, this file may be used under the terms of the GNU -!! General Public License version 2.0 or (at your option) the GNU General -!! Public license version 3 or any later version approved by the KDE Free -!! Qt Foundation. The licenses are as published by the Free Software -!! Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -!! included in the packaging of this file. Please review the following -!! information to ensure the GNU General Public License requirements will -!! be met: https://www.gnu.org/licenses/gpl-2.0.html and -!! https://www.gnu.org/licenses/gpl-3.0.html. -!! -!! $QT_END_LICENSE$ -!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - .section ".text" - - .align 4 - .type q_atomic_test_and_set_int,#function - .global q_atomic_test_and_set_int -q_atomic_test_and_set_int: - cas [%o0],%o1,%o2 - cmp %o1,%o2 - clr %o0 - retl - move %icc,1,%o0 - .size q_atomic_test_and_set_int,.-q_atomic_test_and_set_int - - .align 4 - .type q_atomic_test_and_set_acquire_int,#function - .global q_atomic_test_and_set_acquire_int -q_atomic_test_and_set_acquire_int: - cas [%o0],%o1,%o2 - cmp %o1,%o2 - clr %o0 - membar #LoadLoad | #LoadStore - retl - move %icc,1,%o0 - .size q_atomic_test_and_set_acquire_int,.-q_atomic_test_and_set_acquire_int - - .align 4 - .type q_atomic_test_and_set_release_int,#function - .global q_atomic_test_and_set_release_int -q_atomic_test_and_set_release_int: - membar #LoadStore | #StoreStore - cas [%o0],%o1,%o2 - cmp %o1,%o2 - clr %o0 - retl - move %icc,1,%o0 - .size q_atomic_test_and_set_release_int,.-q_atomic_test_and_set_release_int - - .align 4 - .type q_atomic_test_and_set_ptr,#function - .global q_atomic_test_and_set_ptr -q_atomic_test_and_set_ptr: - casx [%o0],%o1,%o2 - cmp %o1,%o2 - clr %o0 - retl - move %icc,1,%o0 - .size q_atomic_test_and_set_ptr,.-q_atomic_test_and_set_ptr - - .align 4 - .type q_atomic_increment,#function - .global q_atomic_increment -q_atomic_increment: -q_atomic_increment_retry: - ld [%o0],%o3 - add %o3,1,%o4 - cas [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_increment_retry - nop - cmp %o4,-1 - clr %o0 - retl - movne %icc,1,%o0 - .size q_atomic_increment,.-q_atomic_increment - - .align 4 - .type q_atomic_decrement,#function - .global q_atomic_decrement -q_atomic_decrement: -q_atomic_decrement_retry: - ld [%o0],%o3 - add %o3,-1,%o4 - cas [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_decrement_retry - nop - cmp %o4,1 - clr %o0 - retl - movne %icc,1,%o0 - .size q_atomic_decrement,.-q_atomic_decrement - - .align 4 - .type q_atomic_set_int,#function - .global q_atomic_set_int -q_atomic_set_int: -q_atomic_set_int_retry: - ld [%o0],%o2 - cas [%o0],%o2,%o1 - cmp %o2,%o1 - bne q_atomic_set_int_retry - nop - retl - mov %o1,%o0 - .size q_atomic_set_int,.-q_atomic_set_int - - .align 4 - .type q_atomic_set_ptr,#function - .global q_atomic_set_ptr -q_atomic_set_ptr: -q_atomic_set_ptr_retry: - ldx [%o0],%o2 - casx [%o0],%o2,%o1 - cmp %o2,%o1 - bne q_atomic_set_ptr_retry - nop - retl - mov %o1,%o0 - .size q_atomic_set_ptr,.-q_atomic_set_ptr - - .align 4 - .type q_atomic_fetch_and_add_int,#function - .global q_atomic_fetch_and_add_int -q_atomic_fetch_and_add_int: -q_atomic_fetch_and_add_int_retry: - ld [%o0],%o3 - add %o3,%o1,%o4 - cas [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_fetch_and_add_int_retry - nop - retl - mov %o3,%o0 - .size q_atomic_fetch_and_add_int,.-q_atomic_fetch_and_add_int - - .align 4 - .type q_atomic_fetch_and_add_acquire_int,#function - .global q_atomic_fetch_and_add_acquire_int -q_atomic_fetch_and_add_acquire_int: -q_atomic_fetch_and_add_acquire_int_retry: - ld [%o0],%o3 - add %o3,%o1,%o4 - cas [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_fetch_and_add_acquire_int_retry - nop - membar #LoadLoad | #LoadStore - retl - mov %o3,%o0 - .size q_atomic_fetch_and_add_acquire_int,.-q_atomic_fetch_and_add_acquire_int - - .align 4 - .type q_atomic_fetch_and_add_release_int,#function - .global q_atomic_fetch_and_add_release_int -q_atomic_fetch_and_add_release_int: -q_atomic_fetch_and_add_release_int_retry: - membar #LoadStore | #StoreStore - ld [%o0],%o3 - add %o3,%o1,%o4 - cas [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_fetch_and_add_release_int_retry - nop - retl - mov %o3,%o0 - .size q_atomic_fetch_and_add_release_int,.-q_atomic_fetch_and_add_release_int - - .align 4 - .type q_atomic_fetch_and_store_acquire_int,#function - .global q_atomic_fetch_and_store_acquire_int -q_atomic_fetch_and_store_acquire_int: -q_atomic_fetch_and_store_acquire_int_retry: - ld [%o0],%o2 - cas [%o0],%o2,%o1 - cmp %o2,%o1 - bne q_atomic_fetch_and_store_acquire_int_retry - nop - membar #LoadLoad | #LoadStore - retl - mov %o1,%o0 - .size q_atomic_fetch_and_store_acquire_int,.-q_atomic_fetch_and_store_acquire_int - - .align 4 - .type q_atomic_fetch_and_store_release_int,#function - .global q_atomic_fetch_and_store_release_int -q_atomic_fetch_and_store_release_int: -q_atomic_fetch_and_store_release_int_retry: - membar #LoadStore | #StoreStore - ld [%o0],%o2 - cas [%o0],%o2,%o1 - cmp %o2,%o1 - bne q_atomic_fetch_and_store_release_int_retry - nop - retl - mov %o1,%o0 - .size q_atomic_fetch_and_store_release_int,.-q_atomic_fetch_and_store_release_int - - .align 4 - .type q_atomic_test_and_set_acquire_ptr,#function - .global q_atomic_test_and_set_acquire_ptr -q_atomic_test_and_set_acquire_ptr: - casx [%o0],%o1,%o2 - cmp %o1,%o2 - clr %o0 - membar #LoadLoad | #LoadStore - retl - move %icc,1,%o0 - .size q_atomic_test_and_set_acquire_ptr,.-q_atomic_test_and_set_acquire_ptr - - .align 4 - .type q_atomic_test_and_set_release_ptr,#function - .global q_atomic_test_and_set_release_ptr -q_atomic_test_and_set_release_ptr: - membar #LoadStore | #StoreStore - casx [%o0],%o1,%o2 - cmp %o1,%o2 - clr %o0 - retl - move %icc,1,%o0 - .size q_atomic_test_and_set_release_ptr,.-q_atomic_test_and_set_release_ptr - - .align 4 - .type q_atomic_fetch_and_store_acquire_ptr,#function - .global q_atomic_fetch_and_store_acquire_ptr -q_atomic_fetch_and_store_acquire_ptr: -q_atomic_fetch_and_store_acquire_ptr_retry: - ldx [%o0],%o2 - casx [%o0],%o2,%o1 - cmp %o2,%o1 - bne q_atomic_fetch_and_store_acquire_ptr_retry - nop - membar #LoadLoad | #LoadStore - retl - mov %o1,%o0 - .size q_atomic_fetch_and_store_acquire_ptr,.-q_atomic_fetch_and_store_acquire_ptr - - .align 4 - .type q_atomic_fetch_and_store_release_ptr,#function - .global q_atomic_fetch_and_store_release_ptr -q_atomic_fetch_and_store_release_ptr: -q_atomic_fetch_and_store_release_ptr_retry: - membar #LoadStore | #StoreStore - ldx [%o0],%o2 - casx [%o0],%o2,%o1 - cmp %o2,%o1 - bne q_atomic_fetch_and_store_release_ptr_retry - nop - retl - mov %o1,%o0 - .size q_atomic_fetch_and_store_release_ptr,.-q_atomic_fetch_and_store_release_ptr - - .align 4 - .type q_atomic_fetch_and_add_ptr,#function - .global q_atomic_fetch_and_add_ptr -q_atomic_fetch_and_add_ptr: -q_atomic_fetch_and_add_ptr_retry: - ldx [%o0],%o3 - add %o3,%o1,%o4 - casx [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_fetch_and_add_ptr_retry - nop - retl - mov %o3,%o0 - .size q_atomic_fetch_and_add_ptr,.-q_atomic_fetch_and_add_ptr - - .align 4 - .type q_atomic_fetch_and_add_acquire_ptr,#function - .global q_atomic_fetch_and_add_acquire_ptr -q_atomic_fetch_and_add_acquire_ptr: -q_atomic_fetch_and_add_acquire_ptr_retry: - ldx [%o0],%o3 - add %o3,%o1,%o4 - casx [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_fetch_and_add_acquire_ptr_retry - nop - membar #LoadLoad | #LoadStore - retl - mov %o3,%o0 - .size q_atomic_fetch_and_add_acquire_ptr,.-q_atomic_fetch_and_add_acquire_ptr - - .align 4 - .type q_atomic_fetch_and_add_release_ptr,#function - .global q_atomic_fetch_and_add_release_ptr -q_atomic_fetch_and_add_release_ptr: -q_atomic_fetch_and_add_release_ptr_retry: - membar #LoadStore | #StoreStore - ldx [%o0],%o3 - add %o3,%o1,%o4 - casx [%o0],%o3,%o4 - cmp %o3,%o4 - bne q_atomic_fetch_and_add_release_ptr_retry - nop - retl - mov %o3,%o0 - .size q_atomic_fetch_and_add_release_ptr,.-q_atomic_fetch_and_add_release_ptr diff --git a/src/corelib/arch/sparc/qatomic_sparc.cpp b/src/corelib/arch/sparc/qatomic_sparc.cpp deleted file mode 100644 index e481e19739..0000000000 --- a/src/corelib/arch/sparc/qatomic_sparc.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include - -extern "C" { - -int q_atomic_trylock_int(volatile int *addr); -int q_atomic_trylock_ptr(volatile void *addr); - -Q_CORE_EXPORT int q_atomic_lock_int(volatile int *addr) -{ - int returnValue = q_atomic_trylock_int(addr); - - if (returnValue == INT_MIN) { - do { - // spin until we think we can succeed - do { - sched_yield(); - returnValue = *addr; - } while (returnValue == INT_MIN); - - // try again - returnValue = q_atomic_trylock_int(addr); - } while (returnValue == INT_MIN); - } - - return returnValue; -} - -Q_CORE_EXPORT int q_atomic_lock_ptr(volatile void *addr) -{ - int returnValue = q_atomic_trylock_ptr(addr); - - if (returnValue == -1) { - do { - // spin until we think we can succeed - do { - sched_yield(); - returnValue = *reinterpret_cast(addr); - } while (returnValue == -1); - - // try again - returnValue = q_atomic_trylock_ptr(addr); - } while (returnValue == -1); - } - - return returnValue; -} - -} // extern "C" diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index c6d70e578d..bf94386fb2 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -46,42 +46,16 @@ # include // If C++11 atomics are supported, use them! -#elif defined(Q_COMPILER_ATOMICS) && defined(Q_COMPILER_CONSTEXPR) && !defined(QT_ATOMIC_FORCE_NO_CXX11) +#elif defined(Q_COMPILER_ATOMICS) && defined(Q_COMPILER_CONSTEXPR) # include -// The following is used for testing only. -// Note that we don't check the compiler support -- you had better -// know what you're doing if you set it -#elif defined(QT_ATOMIC_FORCE_GCC) -# include - -// Compiler dependent implementation +// We only support one fallback: MSVC, because even on version 2015, it lacks full constexpr support #elif defined(Q_CC_MSVC) # include -// Processor dependent implementation -#elif defined(Q_PROCESSOR_ARM_V7) && defined(Q_PROCESSOR_ARM_32) -# include "QtCore/qatomic_armv7.h" -#elif defined(Q_PROCESSOR_ARM_V6) && defined(Q_PROCESSOR_ARM_32) -# include "QtCore/qatomic_armv6.h" -#elif defined(Q_PROCESSOR_ARM_V5) && defined(Q_PROCESSOR_ARM_32) -# include "QtCore/qatomic_armv5.h" -#elif defined(Q_PROCESSOR_IA64) -# include "QtCore/qatomic_ia64.h" -#elif defined(Q_PROCESSOR_X86) -# include - -// Fallback compiler dependent implementation -#elif defined(Q_CC_GNU) -# include - -// Fallback operating system dependent implementation -#elif defined(Q_OS_UNIX) -# include - // No fallback #else -# error "Qt has not been ported to this platform" +# error "Qt requires C++11 support" #endif QT_BEGIN_NAMESPACE diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char/char.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char/char.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char16_t/char16_t.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char16_t/char16_t.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char32_t/char32_t.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/char32_t/char32_t.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/int/int.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/int/int.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/long/long.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/long/long.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qlonglong/qlonglong.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qlonglong/qlonglong.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qptrdiff/qptrdiff.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qptrdiff/qptrdiff.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/quintptr/quintptr.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/quintptr/quintptr.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qulonglong/qulonglong.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/qulonglong/qulonglong.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/schar/schar.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/schar/schar.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/short/short.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/short/short.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/uchar/uchar.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/uchar/uchar.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/uint/uint.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/uint/uint.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/ulong/ulong.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/ulong/ulong.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/ushort/ushort.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/ushort/ushort.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/no-cxx11/wchar_t/wchar_t.pro deleted file mode 100644 index 64401f0229..0000000000 --- a/tests/auto/corelib/thread/qatomicinteger/no-cxx11/wchar_t/wchar_t.pro +++ /dev/null @@ -1 +0,0 @@ -include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri index 29e9464a4d..f1030d41ef 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri +++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri @@ -2,16 +2,7 @@ TYPE = $$basename(_PRO_FILE_PWD_) dn = $$dirname(_PRO_FILE_PWD_) FORCE = $$basename(dn) - -equals(FORCE, no-cxx11) { - suffix = NoCxx11_$$TYPE - DEFINES += QT_ATOMIC_FORCE_NO_CXX11 -} else: equals(FORCE, gcc) { - suffix = Gcc_$$TYPE - DEFINES += QT_ATOMIC_FORCE_GCC -} else { - suffix = $$TYPE -} +suffix = $$TYPE CONFIG += testcase QT = core testlib diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro index 9d929e649e..09458bd9c3 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro +++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro @@ -16,43 +16,3 @@ SUBDIRS=\ ulong \ ushort \ wchar_t \ - - -contains(QT_CONFIG, c++11)|msvc: SUBDIRS +=\ - no-cxx11/char \ - no-cxx11/char16_t \ - no-cxx11/char32_t \ - no-cxx11/int \ - no-cxx11/long \ - no-cxx11/qlonglong \ - no-cxx11/qptrdiff \ - no-cxx11/quintptr \ - no-cxx11/qulonglong \ - no-cxx11/schar \ - no-cxx11/short \ - no-cxx11/uchar \ - no-cxx11/uint \ - no-cxx11/ulong \ - no-cxx11/ushort \ - no-cxx11/wchar_t \ - - -# The GCC-style atomics only support 32-bit and pointer-sized but add -# them all anyway so we ensure the macros are properly defined -gcc: SUBDIRS +=\ - gcc/char \ - gcc/char16_t \ - gcc/char32_t \ - gcc/int \ - gcc/long \ - gcc/qlonglong \ - gcc/qptrdiff \ - gcc/quintptr \ - gcc/qulonglong \ - gcc/schar \ - gcc/short \ - gcc/uchar \ - gcc/uint \ - gcc/ulong \ - gcc/ushort \ - gcc/wchar_t \ diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 876d15eef0..2950acbe53 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -708,8 +708,8 @@ void tst_Moc::oldStyleCasts() proc.closeWriteChannel(); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); + QCOMPARE(proc.exitCode(), 0); #else QSKIP("Only tested on linux/gcc"); #endif -- cgit v1.2.3