summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-21 08:59:26 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-21 08:59:26 +0100
commitcc920b4cddc170a7442d8fdfb53076c208a3d71e (patch)
treee4757cffe420bd3c61dda1d369b452a0fac9eff7 /src/corelib
parentc8c8cc790a315710b0dae2282dc32e3472e107ee (diff)
parentfc8fd508165c8e4dcfe0da397b63cf99f15178e3 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/arch/arch.pri7
-rw-r--r--src/corelib/arch/qatomic_msvc.h485
-rw-r--r--src/corelib/corelib.pro1
-rw-r--r--src/corelib/global/qglobal.h5
-rw-r--r--src/corelib/global/qlogging.cpp4
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp2
-rw-r--r--src/corelib/kernel/qmetatype.cpp17
-rw-r--r--src/corelib/kernel/qmetatype_p.h2
-rw-r--r--src/corelib/kernel/qobject.cpp8
-rw-r--r--src/corelib/kernel/qobject.h6
-rw-r--r--src/corelib/kernel/qvariant.cpp16
-rw-r--r--src/corelib/kernel/qvariant.h16
-rw-r--r--src/corelib/thread/qatomic_bootstrap.h (renamed from src/corelib/arch/qatomic_bootstrap.h)0
-rw-r--r--src/corelib/thread/qatomic_cxx11.h (renamed from src/corelib/arch/qatomic_cxx11.h)0
-rw-r--r--src/corelib/thread/qbasicatomic.h16
-rw-r--r--src/corelib/thread/qgenericatomic.h3
-rw-r--r--src/corelib/thread/qsemaphore.cpp138
-rw-r--r--src/corelib/thread/thread.pri4
-rw-r--r--src/corelib/tools/qregularexpression.cpp4
-rw-r--r--src/corelib/tools/qregularexpression.h6
-rw-r--r--src/corelib/tools/qshareddata.h12
-rw-r--r--src/corelib/tools/qstring.cpp30
-rw-r--r--src/corelib/tools/qstring.h14
-rw-r--r--src/corelib/tools/qstringlist.cpp22
-rw-r--r--src/corelib/tools/qstringlist.h24
25 files changed, 198 insertions, 644 deletions
diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri
deleted file mode 100644
index e490617c6b..0000000000
--- a/src/corelib/arch/arch.pri
+++ /dev/null
@@ -1,7 +0,0 @@
-win32:HEADERS += arch/qatomic_msvc.h
-
-HEADERS += \
- arch/qatomic_bootstrap.h \
- arch/qatomic_cxx11.h
-
-qtConfig(std-atomic64): QMAKE_USE += libatomic
diff --git a/src/corelib/arch/qatomic_msvc.h b/src/corelib/arch/qatomic_msvc.h
deleted file mode 100644
index 5eae2bdc48..0000000000
--- a/src/corelib/arch/qatomic_msvc.h
+++ /dev/null
@@ -1,485 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** 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_MSVC_H
-#define QATOMIC_MSVC_H
-
-#include <QtCore/qgenericatomic.h>
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// use compiler intrinsics for all atomic functions
-# define QT_INTERLOCKED_PREFIX _
-# define QT_INTERLOCKED_PROTOTYPE
-# define QT_INTERLOCKED_DECLARE_PROTOTYPES
-# define QT_INTERLOCKED_INTRINSIC
-# define Q_ATOMIC_INT16_IS_SUPPORTED
-
-# ifdef _WIN64
-# define Q_ATOMIC_INT64_IS_SUPPORTED
-# endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Prototype declaration
-
-#define QT_INTERLOCKED_CONCAT_I(prefix, suffix) \
- prefix ## suffix
-#define QT_INTERLOCKED_CONCAT(prefix, suffix) \
- QT_INTERLOCKED_CONCAT_I(prefix, suffix)
-
-// MSVC intrinsics prefix function names with an underscore. Also, if platform
-// SDK headers have been included, the Interlocked names may be defined as
-// macros.
-// To avoid double underscores, we paste the prefix with Interlocked first and
-// then the remainder of the function name.
-#define QT_INTERLOCKED_FUNCTION(name) \
- QT_INTERLOCKED_CONCAT( \
- QT_INTERLOCKED_CONCAT(QT_INTERLOCKED_PREFIX, Interlocked), name)
-
-#ifndef QT_INTERLOCKED_VOLATILE
-# define QT_INTERLOCKED_VOLATILE volatile
-#endif
-
-#ifndef QT_INTERLOCKED_PREFIX
-#define QT_INTERLOCKED_PREFIX
-#endif
-
-#ifndef QT_INTERLOCKED_PROTOTYPE
-#define QT_INTERLOCKED_PROTOTYPE
-#endif
-
-#ifdef QT_INTERLOCKED_DECLARE_PROTOTYPES
-#undef QT_INTERLOCKED_DECLARE_PROTOTYPES
-
-extern "C" {
-
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment )(long QT_INTERLOCKED_VOLATILE *);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement )(long QT_INTERLOCKED_VOLATILE *);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange )(long QT_INTERLOCKED_VOLATILE *, long, long);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange )(long QT_INTERLOCKED_VOLATILE *, long);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd )(long QT_INTERLOCKED_VOLATILE *, long);
-
-# if !defined(__i386__) && !defined(_M_IX86)
- void * QT_INTERLOCKED_FUNCTION( CompareExchangePointer )(void * QT_INTERLOCKED_VOLATILE *, void *, void *);
- void * QT_INTERLOCKED_FUNCTION( ExchangePointer )(void * QT_INTERLOCKED_VOLATILE *, void *);
- __int64 QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64);
-# endif
-
-# ifdef Q_ATOMIC_INT16_IS_SUPPORTED
- short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment16 )(short QT_INTERLOCKED_VOLATILE *);
- short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement16 )(short QT_INTERLOCKED_VOLATILE *);
- short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange16 )(short QT_INTERLOCKED_VOLATILE *, short, short);
- short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange16 )(short QT_INTERLOCKED_VOLATILE *, short);
- short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd16 )(short QT_INTERLOCKED_VOLATILE *, short);
-# endif
-# ifdef Q_ATOMIC_INT64_IS_SUPPORTED
- __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment64 )(__int64 QT_INTERLOCKED_VOLATILE *);
- __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement64 )(__int64 QT_INTERLOCKED_VOLATILE *);
- __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64, __int64);
- __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64);
- //above already: qint64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )(qint64 QT_INTERLOCKED_VOLATILE *, qint64);
-# endif
-}
-
-#endif // QT_INTERLOCKED_DECLARE_PROTOTYPES
-
-#undef QT_INTERLOCKED_PROTOTYPE
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#ifdef QT_INTERLOCKED_INTRINSIC
-#undef QT_INTERLOCKED_INTRINSIC
-
-# pragma intrinsic (_InterlockedIncrement)
-# pragma intrinsic (_InterlockedDecrement)
-# pragma intrinsic (_InterlockedExchange)
-# pragma intrinsic (_InterlockedCompareExchange)
-# pragma intrinsic (_InterlockedExchangeAdd)
-
-# if !defined(_M_IX86)
-# pragma intrinsic (_InterlockedCompareExchangePointer)
-# pragma intrinsic (_InterlockedExchangePointer)
-# pragma intrinsic (_InterlockedExchangeAdd64)
-# endif
-
-#endif // QT_INTERLOCKED_INTRINSIC
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Interlocked* replacement macros
-
-#if defined(__i386__) || defined(_M_IX86)
-
-# define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \
- reinterpret_cast<void *>( \
- QT_INTERLOCKED_FUNCTION(CompareExchange)( \
- reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \
- long(newValue), \
- long(expectedValue)))
-
-# define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \
- QT_INTERLOCKED_FUNCTION(Exchange)( \
- reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \
- long(newValue))
-
-# define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \
- QT_INTERLOCKED_FUNCTION(ExchangeAdd)( \
- reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \
- (valueToAdd))
-
-#else // !defined(__i386__) && !defined(_M_IX86)
-
-# define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \
- QT_INTERLOCKED_FUNCTION(CompareExchangePointer)( \
- (void * QT_INTERLOCKED_VOLATILE *)(value), \
- (void *) (newValue), \
- (void *) (expectedValue))
-
-# define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \
- QT_INTERLOCKED_FUNCTION(ExchangePointer)( \
- (void * QT_INTERLOCKED_VOLATILE *)(value), \
- (void *) (newValue))
-
-# define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \
- QT_INTERLOCKED_FUNCTION(ExchangeAdd64)( \
- reinterpret_cast<qint64 QT_INTERLOCKED_VOLATILE *>(value), \
- (valueToAdd))
-
-#endif // !defined(__i386__) && !defined(_M_IX86)
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-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
-
-#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
-# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_WAIT_FREE
-
-# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
-# define Q_ATOMIC_INT16_TEST_AND_SET_IS_WAIT_FREE
-
-# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_WAIT_FREE
-
-# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE
-
-template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
-#endif
-
-#ifdef 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
-
-template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template <int N> struct QAtomicWindowsType { typedef typename QIntegerForSize<N>::Signed Type; };
-template <> struct QAtomicWindowsType<4> { typedef long Type; };
-
-
-template <int N> struct QAtomicOpsBySize : QGenericAtomicOps<QAtomicOpsBySize<N> >
-{
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static bool ref(T &_q_value) Q_DECL_NOTHROW;
- template <typename T> static bool deref(T &_q_value) Q_DECL_NOTHROW;
-
- static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
- template <typename T>
- static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW;
-
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW;
-
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW;
-
-private:
- typedef typename QAtomicWindowsType<N>::Type Type;
- template <typename T> static inline Type *atomic(T *t)
- { Q_STATIC_ASSERT(sizeof(T) == sizeof(Type)); return reinterpret_cast<Type *>(t); }
- template <typename T> static inline Type value(T t)
- { Q_STATIC_ASSERT(sizeof(T) == sizeof(Type)); return Type(t); }
-};
-
-template <typename T>
-struct QAtomicOps : QAtomicOpsBySize<sizeof(T)>
-{
- typedef T Type;
-};
-
-template<> template<typename T>
-inline bool QAtomicOpsBySize<4>::ref(T &_q_value) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Increment)(atomic(&_q_value)) != 0;
-}
-
-template<> template<typename T>
-inline bool QAtomicOpsBySize<4>::deref(T &_q_value) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Decrement)(atomic(&_q_value)) != 0;
-}
-
-template<> template<typename T>
-inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
-}
-
-template<> template <typename T>
-inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
-{
- *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), newValue, expectedValue));
- return *currentValue == expectedValue;
-}
-
-template<> template<typename T>
-inline T QAtomicOpsBySize<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Exchange)(atomic(&_q_value), value(newValue));
-}
-
-template<> template<typename T>
-inline T QAtomicOpsBySize<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(ExchangeAdd)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
-}
-
-#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
-template<> template<typename T>
-inline bool QAtomicOpsBySize<2>::ref(T &_q_value) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Increment16)(atomic(&_q_value)) != 0;
-}
-
-template<> template<typename T>
-inline bool QAtomicOpsBySize<2>::deref(T &_q_value) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Decrement16)(atomic(&_q_value)) != 0;
-}
-
-template<> template<typename T>
-inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
-}
-
-template<> template <typename T>
-inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
-{
- *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), newValue, expectedValue));
- return *currentValue == expectedValue;
-}
-
-template<> template<typename T>
-inline T QAtomicOpsBySize<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Exchange16)(atomic(&_q_value), value(newValue));
-}
-
-template<> template<typename T>
-inline T QAtomicOpsBySize<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(ExchangeAdd16)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
-}
-#endif
-
-#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
-template<> template<typename T>
-inline bool QAtomicOpsBySize<8>::ref(T &_q_value) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Increment64)(atomic(&_q_value)) != 0;
-}
-
-template<> template<typename T>
-inline bool QAtomicOpsBySize<8>::deref(T &_q_value) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Decrement64)(atomic(&_q_value)) != 0;
-}
-
-template<> template<typename T>
-inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
-}
-
-template<> template <typename T>
-inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
-{
- *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), newValue, expectedValue));
- return *currentValue == expectedValue;
-}
-
-template<> template<typename T>
-inline T QAtomicOpsBySize<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(Exchange64)(atomic(&_q_value), value(newValue));
-}
-
-template<> template<typename T>
-inline T QAtomicOpsBySize<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_FUNCTION(ExchangeAdd64)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
-}
-#endif
-
-// Specialization for pointer types, since we have Interlocked*Pointer() variants in some configurations
-template <typename T>
-struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> >
-{
- typedef T *Type;
-
- static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
- static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) Q_DECL_NOTHROW;
- static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW;
-
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
- static T *fetchAndStoreRelaxed(T *&_q_value, T *newValue) Q_DECL_NOTHROW;
-
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return true; }
- static T *fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) Q_DECL_NOTHROW;
-};
-
-template <typename T>
-inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) Q_DECL_NOTHROW
-{
- return QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue) == expectedValue;
-}
-
-template <typename T>
-inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW
-{
- *currentValue = reinterpret_cast<T *>(QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue));
- return *currentValue == expectedValue;
-}
-
-template <typename T>
-inline T *QAtomicOps<T *>::fetchAndStoreRelaxed(T *&_q_value, T *newValue) Q_DECL_NOTHROW
-{
- return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, newValue));
-}
-
-template <typename T>
-inline T *QAtomicOps<T *>::fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) Q_DECL_NOTHROW
-{
- return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_ADD_POINTER(&_q_value, valueToAdd * sizeof(T)));
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Cleanup
-
-#undef QT_INTERLOCKED_CONCAT_I
-#undef QT_INTERLOCKED_CONCAT
-#undef QT_INTERLOCKED_FUNCTION
-#undef QT_INTERLOCKED_PREFIX
-
-#undef QT_INTERLOCKED_VOLATILE
-
-#undef QT_INTERLOCKED_INCREMENT
-#undef QT_INTERLOCKED_DECREMENT
-#undef QT_INTERLOCKED_COMPARE_EXCHANGE
-#undef QT_INTERLOCKED_EXCHANGE
-#undef QT_INTERLOCKED_EXCHANGE_ADD
-#undef QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER
-#undef QT_INTERLOCKED_EXCHANGE_POINTER
-#undef QT_INTERLOCKED_EXCHANGE_ADD_POINTER
-
-QT_END_NAMESPACE
-#endif // QATOMIC_MSVC_H
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 3db2e2ceb8..7f62a6f1b0 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -32,7 +32,6 @@ ANDROID_PERMISSIONS = \
freebsd|openbsd: QMAKE_LFLAGS_NOUNDEF =
include(animation/animation.pri)
-include(arch/arch.pri)
include(global/global.pri)
include(thread/thread.pri)
include(tools/tools.pri)
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 33885021ba..e31d4d9ad7 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -747,12 +747,13 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qSharedBuild() Q_DECL_NOTHROW;
# define QT_DEBUG
#endif
+// QtPrivate::asString defined in qstring.h
#ifndef qPrintable
-# define qPrintable(string) QString(string).toLocal8Bit().constData()
+# define qPrintable(string) QtPrivate::asString(string).toLocal8Bit().constData()
#endif
#ifndef qUtf8Printable
-# define qUtf8Printable(string) QString(string).toUtf8().constData()
+# define qUtf8Printable(string) QtPrivate::asString(string).toUtf8().constData()
#endif
/*
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 99c57c3b7a..17002c4231 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -91,8 +91,7 @@
# include "private/qcore_unix_p.h"
#endif
-#ifndef QT_BOOTSTRAPPED
-#if !defined QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
# ifdef __UCLIBC__
# if __UCLIBC_HAS_BACKTRACE__
# define QLOGGING_HAVE_BACKTRACE
@@ -106,6 +105,7 @@
extern char *__progname;
#endif
+#ifndef QT_BOOTSTRAPPED
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_INCLUDE(<sys/syscall.h>))
# include <sys/syscall.h>
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index e49edd9a40..748ce67dac 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -42,7 +42,9 @@
#include <qfile.h>
#include <qhash.h>
#include <qtextstream.h>
+#if QT_CONFIG(regularexpression)
#include <qregularexpression.h>
+#endif
#include <private/qfilesystemengine_p.h>
#include <errno.h>
#include <stdlib.h>
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 5abc2ebd70..518381712a 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -53,12 +53,15 @@
#include "qdatastream.h"
#include "qmetatypeswitcher_p.h"
+#if QT_CONFIG(regularexpression)
+# include "qregularexpression.h"
+#endif
+
#ifndef QT_BOOTSTRAPPED
# include "qbitarray.h"
# include "qurl.h"
# include "qvariant.h"
# include "qabstractitemmodel.h"
-# include "qregularexpression.h"
# include "qjsonvalue.h"
# include "qjsonobject.h"
# include "qjsonarray.h"
@@ -1481,12 +1484,12 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
stream << *static_cast<const NS(QRegExp)*>(data);
break;
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
case QMetaType::QRegularExpression:
stream << *static_cast<const NS(QRegularExpression)*>(data);
break;
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
+#ifndef QT_BOOTSTRAPPED
case QMetaType::QEasingCurve:
stream << *static_cast<const NS(QEasingCurve)*>(data);
break;
@@ -1711,12 +1714,12 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
stream >> *static_cast< NS(QRegExp)*>(data);
break;
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
case QMetaType::QRegularExpression:
stream >> *static_cast< NS(QRegularExpression)*>(data);
break;
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
+#ifndef QT_BOOTSTRAPPED
case QMetaType::QEasingCurve:
stream >> *static_cast< NS(QEasingCurve)*>(data);
break;
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h
index 6f1334d082..0bf6bcb922 100644
--- a/src/corelib/kernel/qmetatype_p.h
+++ b/src/corelib/kernel/qmetatype_p.h
@@ -219,7 +219,7 @@ template<> struct TypeDefinition<QPointF> { static const bool IsAvailable = fals
#ifdef QT_NO_REGEXP
template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = false; };
#endif
-#if defined(QT_BOOTSTRAPPED) || defined(QT_NO_REGULAREXPRESSION)
+#if !QT_CONFIG(regularexpression)
template<> struct TypeDefinition<QRegularExpression> { static const bool IsAvailable = false; };
#endif
#ifdef QT_NO_SHORTCUT
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 9e1c3a50cb..dcc1bb5814 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -50,7 +50,9 @@
#include "qvariant.h"
#include "qmetaobject.h"
#include <qregexp.h>
-#include <qregularexpression.h>
+#if QT_CONFIG(regularexpression)
+# include <qregularexpression.h>
+#endif
#include <qthread.h>
#include <private/qthread_p.h>
#include <qdebug.h>
@@ -1921,7 +1923,7 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegExp &re,
}
#endif // QT_NO_REGEXP
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
/*!
\internal
*/
@@ -1943,7 +1945,7 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re
qt_qFindChildren_helper(obj, re, mo, list, options);
}
}
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
/*!
\internal
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 0e608a3208..aac9bcdee9 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -74,7 +74,7 @@ class QWidget;
#ifndef QT_NO_REGEXP
class QRegExp;
#endif
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
class QRegularExpression;
#endif
#ifndef QT_NO_USERDATA
@@ -187,7 +187,7 @@ public:
}
#endif
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
template<typename T>
inline QList<T> findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
@@ -197,7 +197,7 @@ public:
reinterpret_cast<QList<void *> *>(&list), options);
return list;
}
-#endif
+#endif // QT_CONFIG(regularexpression)
inline const QObjectList &children() const { return d_ptr->children; }
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index f77831c703..c3c36e05d7 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -48,7 +48,9 @@
#include "qdatetime.h"
#include "qeasingcurve.h"
#include "qlist.h"
+#if QT_CONFIG(regularexpression)
#include "qregularexpression.h"
+#endif
#include "qstring.h"
#include "qstringlist.h"
#include "qurl.h"
@@ -1941,12 +1943,12 @@ QVariant::QVariant(const QRegExp &regExp)
: d(RegExp)
{ v_construct<QRegExp>(&d, regExp); }
#endif // QT_NO_REGEXP
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
QVariant::QVariant(const QRegularExpression &re)
: d(RegularExpression)
{ v_construct<QRegularExpression>(&d, re); }
-#endif
+#endif // QT_CONFIG(regularexpression)
+#ifndef QT_BOOTSTRAPPED
QVariant::QVariant(const QUuid &uuid)
: d(Uuid)
{ v_construct<QUuid>(&d, uuid); }
@@ -2650,7 +2652,7 @@ QRegExp QVariant::toRegExp() const
}
#endif
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(regularexpression)
/*!
\fn QRegularExpression QVariant::toRegularExpression() const
\since 5.0
@@ -2660,13 +2662,13 @@ QRegExp QVariant::toRegExp() const
\sa canConvert(), convert()
*/
-#ifndef QT_NO_REGULAREXPRESSION
QRegularExpression QVariant::toRegularExpression() const
{
return qVariantToHelper<QRegularExpression>(d, handlerManager);
}
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
+#ifndef QT_BOOTSTRAPPED
/*!
\since 5.0
@@ -2758,7 +2760,7 @@ QJsonDocument QVariant::toJsonDocument() const
{
return qVariantToHelper<QJsonDocument>(d, handlerManager);
}
-#endif
+#endif // QT_BOOTSTRAPPED
/*!
\fn QChar QVariant::toChar() const
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 1dc4b56e9b..b554ea4906 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -81,9 +81,9 @@ class QRectF;
#ifndef QT_NO_REGEXP
class QRegExp;
#endif // QT_NO_REGEXP
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
class QRegularExpression;
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
class QTextFormat;
class QTextLength;
class QUrl;
@@ -248,10 +248,10 @@ class Q_CORE_EXPORT QVariant
#ifndef QT_NO_REGEXP
QVariant(const QRegExp &regExp);
#endif // QT_NO_REGEXP
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
QVariant(const QRegularExpression &re);
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
+#ifndef QT_BOOTSTRAPPED
QVariant(const QUrl &url);
QVariant(const QEasingCurve &easing);
QVariant(const QUuid &uuid);
@@ -322,10 +322,10 @@ class Q_CORE_EXPORT QVariant
#ifndef QT_NO_REGEXP
QRegExp toRegExp() const;
#endif // QT_NO_REGEXP
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
QRegularExpression toRegularExpression() const;
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
+#ifndef QT_BOOTSTRAPPED
QUrl toUrl() const;
QEasingCurve toEasingCurve() const;
QUuid toUuid() const;
diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/thread/qatomic_bootstrap.h
index b463f817bd..b463f817bd 100644
--- a/src/corelib/arch/qatomic_bootstrap.h
+++ b/src/corelib/thread/qatomic_bootstrap.h
diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/thread/qatomic_cxx11.h
index 2fc0bf5419..2fc0bf5419 100644
--- a/src/corelib/arch/qatomic_cxx11.h
+++ b/src/corelib/thread/qatomic_cxx11.h
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 92db7a6228..aacd12f220 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -45,20 +45,8 @@
#if defined(QT_BOOTSTRAPPED)
# include <QtCore/qatomic_bootstrap.h>
-
-// If C++11 atomics are supported, use them!
-// Note that constexpr support is sometimes disabled in QNX builds but its
-// library has <atomic>.
-#elif defined(Q_COMPILER_ATOMICS) && (defined(Q_COMPILER_CONSTEXPR) || defined(Q_OS_QNX))
-# include <QtCore/qatomic_cxx11.h>
-
-// We only support one fallback: MSVC, because even on version 2015, it lacks full constexpr support
-#elif defined(Q_CC_MSVC)
-# include <QtCore/qatomic_msvc.h>
-
-// No fallback
#else
-# error "Qt requires C++11 support"
+# include <QtCore/qatomic_cxx11.h>
#endif
QT_WARNING_PUSH
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index 5c4c02a2ec..89c4fe9a11 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -253,12 +253,15 @@ template <typename BaseClass> struct QGenericAtomicOps
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
}
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_MSVC(4146) // unary minus operator applied to unsigned type, result still unsigned
template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
// implement fetchAndSub on top of fetchAndAdd
return fetchAndAddRelaxed(_q_value, -operand);
}
+QT_WARNING_POP
template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 6497792bf5..6c4a211222 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2017 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -119,28 +119,44 @@ using namespace QtFutex;
acquire tokens. Which ones get woken up is unspecified.
If the system has the ability to wake up a precise number of threads, has
- Linux's FUTEX_WAKE_OP functionality, and is 64-bit, we'll use the high word
- as a copy of the low word, but the sign bit indicating the presence of a
- thread waiting for multiple tokens. So when releasing n tokens on those
- systems, we tell the kernel to wake up n single-token threads and all of
- the multi-token ones, then clear that wait bit. Which threads get woken up
- is unspecified, but it's likely single-token threads will get woken up
- first.
+ Linux's FUTEX_WAKE_OP functionality, and is 64-bit, instead of using a
+ single bit indicating a contended semaphore, we'll store the total number
+ of waiters in the high word. Additionally, all multi-token waiters will be
+ waiting on that high word. So when releasing n tokens on those systems, we
+ tell the kernel to wake up n single-token threads and all of the
+ multi-token ones. Which threads get woken up is unspecified, but it's
+ likely single-token threads will get woken up first.
*/
-static const quint32 futexContendedBit = 1U << 31;
+
+#if defined(FUTEX_OP) && QT_POINTER_SIZE > 4
+static Q_CONSTEXPR bool futexHasWaiterCount = true;
+#else
+static Q_CONSTEXPR bool futexHasWaiterCount = false;
+#endif
+
+static const quintptr futexNeedsWakeAllBit =
+ Q_UINT64_C(1) << (sizeof(quintptr) * CHAR_BIT - 1);
static int futexAvailCounter(quintptr v)
{
// the low 31 bits
- return int(v & (futexContendedBit - 1));
+ if (futexHasWaiterCount) {
+ // the high bit of the low word isn't used
+ Q_ASSERT((v & 0x80000000U) == 0);
+
+ // so we can be a little faster
+ return int(unsigned(v));
+ }
+ return int(v & 0x7fffffffU);
}
-static quintptr futexCounterParcel(int n)
+static bool futexNeedsWake(quintptr v)
{
- // replicate the 31 bits if we're on 64-bit
- quint64 nn = quint32(n);
- nn |= (nn << 32);
- return quintptr(nn);
+ // If we're counting waiters, the number of waiters is stored in the low 31
+ // bits of the high word (that is, bits 32-62). If we're not, then we use
+ // bit 31 to indicate anyone is waiting. Either way, if any bit 31 or above
+ // is set, there are waiters.
+ return v >> 31;
}
static QBasicAtomicInteger<quint32> *futexLow32(QBasicAtomicInteger<quintptr> *ptr)
@@ -152,9 +168,6 @@ static QBasicAtomicInteger<quint32> *futexLow32(QBasicAtomicInteger<quintptr> *p
return result;
}
-#ifdef FUTEX_OP
-// quintptr might be 32bit, in which case we want this to be 0, without implicitly casting.
-static const quintptr futexMultiWaiterBit = static_cast<quintptr>(Q_UINT64_C(1) << 63);
static QBasicAtomicInteger<quint32> *futexHigh32(QBasicAtomicInteger<quintptr> *ptr)
{
auto result = reinterpret_cast<QBasicAtomicInteger<quint32> *>(ptr);
@@ -163,18 +176,21 @@ static QBasicAtomicInteger<quint32> *futexHigh32(QBasicAtomicInteger<quintptr> *
#endif
return result;
}
-#endif
-template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintptr> &u, int n, int timeout)
+template <bool IsTimed> bool
+futexSemaphoreTryAcquire_loop(QBasicAtomicInteger<quintptr> &u, quintptr curValue, quintptr nn, int timeout)
{
QDeadlineTimer timer(IsTimed ? QDeadlineTimer(timeout) : QDeadlineTimer());
- quintptr curValue = u.loadAcquire();
qint64 remainingTime = timeout * Q_INT64_C(1000) * 1000;
+ int n = int(unsigned(nn));
+
+ // we're called after one testAndSet, so start by waiting first
+ goto start_wait;
+
forever {
- int available = futexAvailCounter(curValue);
- if (available >= n) {
+ if (futexAvailCounter(curValue) >= n) {
// try to acquire
- quintptr newValue = curValue - futexCounterParcel(n);
+ quintptr newValue = curValue - nn;
if (u.testAndSetOrdered(curValue, newValue, curValue))
return true; // succeeded!
continue;
@@ -184,19 +200,18 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
if (remainingTime == 0)
return false;
- // set the contended and multi-wait bits
- quintptr bitsToSet = futexContendedBit;
+ // indicate we're waiting
+start_wait:
auto ptr = futexLow32(&u);
-#ifdef FUTEX_OP
- if (n > 1 && sizeof(curValue) >= sizeof(int)) {
- bitsToSet |= futexMultiWaiterBit;
- ptr = futexHigh32(&u);
+ if (n > 1 || !futexHasWaiterCount) {
+ u.fetchAndOrRelaxed(futexNeedsWakeAllBit);
+ curValue |= futexNeedsWakeAllBit;
+ if (n > 1 && futexHasWaiterCount) {
+ ptr = futexHigh32(&u);
+ //curValue >>= 32; // but this is UB in 32-bit, so roundabout:
+ curValue = quint64(curValue) >> 32;
+ }
}
-#endif
-
- // the value is the same for either branch
- u.fetchAndOrRelaxed(bitsToSet);
- curValue |= bitsToSet;
if (IsTimed && remainingTime > 0) {
bool timedout = !futexWait(*ptr, curValue, remainingTime);
@@ -212,6 +227,47 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
}
}
+template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintptr> &u, int n, int timeout)
+{
+ // Try to acquire without waiting (we still loop because the testAndSet
+ // call can fail).
+ quintptr curValue = u.loadAcquire();
+ while (futexAvailCounter(curValue) >= n) {
+ // try to acquire
+ quintptr newValue = curValue - n;
+ if (u.testAndSetOrdered(curValue, newValue, curValue))
+ return true; // succeeded!
+ }
+ if (timeout == 0)
+ return false;
+
+ // we need to wait
+ quintptr valueToSubtract = unsigned(n);
+ quintptr oneWaiter = quintptr(Q_UINT64_C(1) << 32); // zero on 32-bit
+ if (futexHasWaiterCount) {
+ // increase the waiter count
+ u.fetchAndAddRelaxed(oneWaiter);
+
+ // We don't use the fetched value from above so futexWait() fails if
+ // it changed after the testAndSetOrdered above.
+ curValue += oneWaiter;
+
+ // Also adjust valueToSubtract to subtract oneWaiter when we succeed in
+ // acquiring.
+ valueToSubtract += oneWaiter;
+ }
+
+ if (futexSemaphoreTryAcquire_loop<IsTimed>(u, curValue, valueToSubtract, timeout))
+ return true;
+
+ if (futexHasWaiterCount) {
+ // decrement the number of threads waiting
+ Q_ASSERT(futexHigh32(&u)->load() & 0x7fffffffU);
+ u.fetchAndSubRelaxed(oneWaiter);
+ }
+ return false;
+}
+
class QSemaphorePrivate {
public:
inline QSemaphorePrivate(int n) : avail(n) { }
@@ -289,10 +345,10 @@ void QSemaphore::release(int n)
Q_ASSERT_X(n >= 0, "QSemaphore::release", "parameter 'n' must be non-negative");
if (futexAvailable()) {
- quintptr prevValue = u.fetchAndAddRelease(futexCounterParcel(n));
- if (prevValue & futexContendedBit) {
+ quintptr prevValue = u.fetchAndAddRelease(n);
+ if (futexNeedsWake(prevValue)) {
#ifdef FUTEX_OP
- if (sizeof(u) == sizeof(int)) {
+ if (!futexHasWaiterCount) {
/*
On 32-bit systems, all waiters are waiting on the same address,
so we'll wake them all and ask the kernel to clear the high bit.
@@ -317,9 +373,6 @@ void QSemaphore::release(int n)
the kernel to wake up n single-token waiters and all multi-token
waiters (if any), then clear the multi-token wait bit.
- That means we must clear the contention bit ourselves. See
- below for handling the race.
-
atomic {
int oldval = *upper;
*upper = oldval & ~(1 << 31);
@@ -332,7 +385,6 @@ void QSemaphore::release(int n)
quint32 oparg = 31;
quint32 cmp = FUTEX_OP_CMP_LT;
quint32 cmparg = 0;
- futexLow32(&u)->fetchAndAndRelease(futexContendedBit - 1);
futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
}
#else
@@ -343,7 +395,7 @@ void QSemaphore::release(int n)
// its acquisition anyway, so it has to wait;
// 2) it did not see the new counter value, in which case its
// futexWait will fail.
- u.fetchAndAndRelease(futexContendedBit - 1);
+ u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
futexWakeAll(u);
#endif
}
diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri
index e4972a57b3..47775f3fde 100644
--- a/src/corelib/thread/thread.pri
+++ b/src/corelib/thread/thread.pri
@@ -10,6 +10,8 @@ HEADERS += thread/qmutex.h \
thread/qthreadstorage.h \
thread/qwaitcondition.h \
thread/qatomic.h \
+ thread/qatomic_bootstrap.h \
+ thread/qatomic_cxx11.h \
thread/qbasicatomic.h \
thread/qgenericatomic.h
@@ -67,3 +69,5 @@ win32 {
thread/qthread_unix.cpp \
thread/qwaitcondition_unix.cpp
}
+
+qtConfig(std-atomic64): QMAKE_USE += libatomic
diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp
index 86bc99716d..13eff07c04 100644
--- a/src/corelib/tools/qregularexpression.cpp
+++ b/src/corelib/tools/qregularexpression.cpp
@@ -41,8 +41,6 @@
#include "qregularexpression.h"
-#ifndef QT_NO_REGULAREXPRESSION
-
#include <QtCore/qcoreapplication.h>
#include <QtCore/qhashfunctions.h>
#include <QtCore/qreadwritelock.h>
@@ -2912,5 +2910,3 @@ static const char *pcreCompileErrorCodes[] =
#endif // #if 0
QT_END_NAMESPACE
-
-#endif // QT_NO_REGULAREXPRESSION
diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/tools/qregularexpression.h
index 050841e70e..398fc9ec9c 100644
--- a/src/corelib/tools/qregularexpression.h
+++ b/src/corelib/tools/qregularexpression.h
@@ -43,13 +43,13 @@
#include <QtCore/qglobal.h>
-#ifndef QT_NO_REGULAREXPRESSION
-
#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qvariant.h>
+QT_REQUIRE_CONFIG(regularexpression);
+
QT_BEGIN_NAMESPACE
class QStringView;
@@ -277,6 +277,4 @@ Q_DECLARE_SHARED(QRegularExpressionMatchIterator)
QT_END_NAMESPACE
-#endif // QT_NO_REGULAREXPRESSION
-
#endif // QREGULAREXPRESSION_H
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index f5572f3a00..3ef134a99d 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -115,7 +115,11 @@ public:
#ifdef Q_COMPILER_RVALUE_REFS
QSharedDataPointer(QSharedDataPointer &&o) Q_DECL_NOTHROW : d(o.d) { o.d = nullptr; }
inline QSharedDataPointer<T> &operator=(QSharedDataPointer<T> &&other) Q_DECL_NOTHROW
- { qSwap(d, other.d); return *this; }
+ {
+ QSharedDataPointer moved(std::move(other));
+ swap(moved);
+ return *this;
+ }
#endif
inline bool operator!() const { return !d; }
@@ -216,7 +220,11 @@ public:
#ifdef Q_COMPILER_RVALUE_REFS
inline QExplicitlySharedDataPointer(QExplicitlySharedDataPointer &&o) Q_DECL_NOTHROW : d(o.d) { o.d = nullptr; }
inline QExplicitlySharedDataPointer<T> &operator=(QExplicitlySharedDataPointer<T> &&other) Q_DECL_NOTHROW
- { qSwap(d, other.d); return *this; }
+ {
+ QExplicitlySharedDataPointer moved(std::move(other));
+ swap(moved);
+ return *this;
+ }
#endif
inline bool operator!() const { return !d; }
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index ed56f99771..46ec8b072c 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -40,7 +40,9 @@
#include "qstringlist.h"
#include "qregexp.h"
+#if QT_CONFIG(regularexpression)
#include "qregularexpression.h"
+#endif
#include "qunicodetables_p.h"
#ifndef QT_NO_TEXTCODEC
#include <qtextcodec.h>
@@ -3695,7 +3697,7 @@ int QString::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs
}
-#if !(defined(QT_NO_REGEXP) && defined(QT_NO_REGULAREXPRESSION))
+#if !(defined(QT_NO_REGEXP) && !QT_CONFIG(regularexpression))
struct QStringCapture
{
int pos;
@@ -3862,8 +3864,7 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
}
#endif
-#ifndef QT_NO_REGULAREXPRESSION
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(regularexpression)
/*!
\overload replace()
\since 5.0
@@ -3991,8 +3992,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after)
return *this;
}
-#endif // QT_BOOTSTRAPPED
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
/*!
Returns the number of (potentially overlapping) occurrences of
@@ -4207,8 +4207,7 @@ int QString::count(const QRegExp& rx) const
}
#endif // QT_NO_REGEXP
-#ifndef QT_NO_REGULAREXPRESSION
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(regularexpression)
/*!
\overload indexOf()
\since 5.0
@@ -4386,8 +4385,7 @@ int QString::count(const QRegularExpression &re) const
}
return count;
}
-#endif // QT_BOOTSTRAPPED
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
/*! \fn int QString::count() const
@@ -4509,7 +4507,7 @@ QString QString::section(const QString &sep, int start, int end, SectionFlags fl
return ret;
}
-#if !(defined(QT_NO_REGEXP) && defined(QT_NO_REGULAREXPRESSION))
+#if !(defined(QT_NO_REGEXP) && !QT_CONFIG(regularexpression))
class qt_section_chunk {
public:
qt_section_chunk() {}
@@ -4619,8 +4617,7 @@ QString QString::section(const QRegExp &reg, int start, int end, SectionFlags fl
}
#endif
-#ifndef QT_NO_REGULAREXPRESSION
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(regularexpression)
/*!
\overload section()
\since 5.0
@@ -4664,8 +4661,7 @@ QString QString::section(const QRegularExpression &re, int start, int end, Secti
return extractSections(sections, start, end, flags);
}
-#endif // QT_BOOTSTRAPPED
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
/*!
Returns a substring that contains the \a n leftmost characters
@@ -7630,8 +7626,7 @@ QVector<QStringRef> QString::splitRef(const QRegExp &rx, SplitBehavior behavior)
}
#endif
-#ifndef QT_NO_REGULAREXPRESSION
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(regularexpression)
namespace {
template<class ResultList, typename MidMethod>
static ResultList splitString(const QString &source, MidMethod mid, const QRegularExpression &re,
@@ -7711,8 +7706,7 @@ QVector<QStringRef> QString::splitRef(const QRegularExpression &re, SplitBehavio
{
return splitString<QVector<QStringRef> >(*this, &QString::midRef, re, behavior);
}
-#endif // QT_BOOTSTRAPPED
-#endif // QT_NO_REGULAREXPRESSION
+#endif // QT_CONFIG(regularexpression)
/*!
\enum QString::NormalizationForm
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index d93891248f..447f000486 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -353,7 +353,7 @@ public:
inline bool contains(QRegExp &rx) const { return indexOf(rx) != -1; }
#endif
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
int indexOf(const QRegularExpression &re, int from = 0) const;
int indexOf(const QRegularExpression &re, int from, QRegularExpressionMatch *rmatch) const; // ### Qt 6: merge overloads
int lastIndexOf(const QRegularExpression &re, int from = -1) const;
@@ -377,7 +377,7 @@ public:
#ifndef QT_NO_REGEXP
QString section(const QRegExp &reg, int start, int end = -1, SectionFlags flags = SectionDefault) const;
#endif
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
QString section(const QRegularExpression &re, int start, int end = -1, SectionFlags flags = SectionDefault) const;
#endif
Q_REQUIRED_RESULT QString left(int n) const;
@@ -505,7 +505,7 @@ public:
inline QString &remove(const QRegExp &rx)
{ return replace(rx, QString()); }
#endif
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
QString &replace(const QRegularExpression &re, const QString &after);
inline QString &remove(const QRegularExpression &re)
{ return replace(re, QString()); }
@@ -525,7 +525,7 @@ public:
Q_REQUIRED_RESULT QStringList split(const QRegExp &sep, SplitBehavior behavior = KeepEmptyParts) const;
Q_REQUIRED_RESULT QVector<QStringRef> splitRef(const QRegExp &sep, SplitBehavior behavior = KeepEmptyParts) const;
#endif
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
Q_REQUIRED_RESULT QStringList split(const QRegularExpression &sep, SplitBehavior behavior = KeepEmptyParts) const;
Q_REQUIRED_RESULT QVector<QStringRef> splitRef(const QRegularExpression &sep, SplitBehavior behavior = KeepEmptyParts) const;
#endif
@@ -1860,6 +1860,12 @@ QT_DEPRECATED inline QString escape(const QString &plain) {
#endif
}
+namespace QtPrivate {
+// used by qPrintable() and qUtf8Printable() macros
+inline const QString &asString(const QString &s) { return s; }
+inline QString &&asString(QString &&s) { return std::move(s); }
+}
+
QT_END_NAMESPACE
#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index 17f6bd8539..d10d9ad9d0 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -39,7 +39,9 @@
#include <qstringlist.h>
#include <qset.h>
-#include <qregularexpression.h>
+#if QT_CONFIG(regularexpression)
+# include <qregularexpression.h>
+#endif
#include <algorithm>
@@ -361,8 +363,7 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegExp
}
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
/*!
\fn QStringList QStringList::filter(const QRegularExpression &re) const
\overload
@@ -380,8 +381,7 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegula
}
return res;
}
-#endif // QT_NO_REGULAREXPRESSION
-#endif // QT_BOOTSTRAPPED
+#endif // QT_CONFIG(regularexpression)
/*!
\fn QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
@@ -436,8 +436,7 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegExp &r
}
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
/*!
\fn QStringList &QStringList::replaceInStrings(const QRegularExpression &re, const QString &after)
\overload
@@ -466,8 +465,7 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularEx
for (int i = 0; i < that->size(); ++i)
(*that)[i].replace(re, after);
}
-#endif // QT_NO_REGULAREXPRESSION
-#endif // QT_BOOTSTRAPPED
+#endif // QT_CONFIG(regularexpression)
static int accumulatedSize(const QStringList &list, int seplen)
{
@@ -674,8 +672,7 @@ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, QRegExp &rx, int
}
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
/*!
\fn int QStringList::indexOf(const QRegularExpression &re, int from) const
\overload
@@ -732,8 +729,7 @@ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegularEx
}
return -1;
}
-#endif // QT_NO_REGULAREXPRESSION
-#endif // QT_BOOTSTRAPPED
+#endif // QT_CONFIG(regularexpression)
/*!
\fn int QStringList::removeDuplicates()
diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h
index b11856d9be..e58445b8c0 100644
--- a/src/corelib/tools/qstringlist.h
+++ b/src/corelib/tools/qstringlist.h
@@ -84,12 +84,10 @@ public:
inline QStringList &replaceInStrings(const QRegExp &rx, const QString &after);
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
inline QStringList filter(const QRegularExpression &re) const;
inline QStringList &replaceInStrings(const QRegularExpression &re, const QString &after);
-#endif // QT_NO_REGULAREXPRESSION
-#endif // QT_BOOTSTRAPPED
+#endif // QT_CONFIG(regularexpression)
#ifndef Q_QDOC
private:
@@ -138,12 +136,10 @@ public:
inline int lastIndexOf(QRegExp &rx, int from = -1) const;
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
inline int indexOf(const QRegularExpression &re, int from = 0) const;
inline int lastIndexOf(const QRegularExpression &re, int from = -1) const;
-#endif // QT_NO_REGULAREXPRESSION
-#endif // QT_BOOTSTRAPPED
+#endif // QT_CONFIG(regularexpression)
using QList<QString>::indexOf;
using QList<QString>::lastIndexOf;
@@ -179,14 +175,12 @@ namespace QtPrivate {
int Q_CORE_EXPORT QStringList_lastIndexOf(const QStringList *that, QRegExp &rx, int from);
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QRegularExpression &rx, const QString &after);
QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QRegularExpression &re);
int Q_CORE_EXPORT QStringList_indexOf(const QStringList *that, const QRegularExpression &re, int from);
int Q_CORE_EXPORT QStringList_lastIndexOf(const QStringList *that, const QRegularExpression &re, int from);
-#endif // QT_NO_REGULAREXPRESSION
-#endif // QT_BOOTSTRAPPED
+#endif // QT_CONFIG(regularexpression)
}
inline void QListSpecialMethods<QString>::sort(Qt::CaseSensitivity cs)
@@ -275,8 +269,7 @@ inline int QStringList::lastIndexOf(QRegExp &rx, int from) const
}
#endif
-#ifndef QT_BOOTSTRAPPED
-#ifndef QT_NO_REGULAREXPRESSION
+#if QT_CONFIG(regularexpression)
inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QRegularExpression &rx, const QString &after)
{
QtPrivate::QStringList_replaceInStrings(self(), rx, after);
@@ -297,8 +290,7 @@ inline int QStringList::lastIndexOf(const QRegularExpression &rx, int from) cons
{
return QtPrivate::QStringList_lastIndexOf(this, rx, from);
}
-#endif // QT_NO_REGULAREXPRESSION
-#endif // QT_BOOTSTRAPPED
+#endif // QT_CONFIG(regularexpression)
#endif // Q_QDOC
QT_END_NAMESPACE