Auto-detect whether 64-bit std::atomic really works
The C++ standard says it must, but some badly-configured toolchains seem to be lacking support. In particular, for some 32-bit platforms without native support for them, GCC implements 64-bit atomics via out-of-line functions in libatomic. If that library is missing... well, then std::atomic 64-bit doesn't work and we mustn't try to use it. This was found when trying to compile Qt 5.6 for MIPS 32-bit: Linking library libQt5Core.so.5.6.0 .obj/qsimd.o: In function `std::__atomic_base<unsigned long long>::load(std::memory_order) const': /opt/poky/1.7/sysroots/mips32r2-poky-linux/usr/include/c++/4.9.1/bits/atomic_base.h:500: undefined reference to `__atomic_load_8' .obj/qsimd.o: In function `std::__atomic_base<unsigned long long>::store(unsigned long long, std::memory_order)': /opt/poky/1.7/sysroots/mips32r2-poky-linux/usr/include/c++/4.9.1/bits/atomic_base.h:478: undefined reference to `__atomic_store_8' Yocto bug report: https://bugzilla.yoctoproject.org/show_bug.cgi?id=8274 Change-Id: I42e7ef1a481840699a8dffff140224d6614e5c36 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 3d7586b760550b7d89594c8d7462fc30b868ecc6) Reviewed-by: Dmitry Shachnev <mitya57@gmail.com>
This commit is contained in:
parent
6c222297ab
commit
2398e225ab
54
config.tests/common/atomic64/atomic64.cpp
Normal file
54
config.tests/common/atomic64/atomic64.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Intel Corporation.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the FOO module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** 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 http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://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 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
void test(volatile std::atomic<std::int64_t> &a)
|
||||
{
|
||||
std::int64_t v = a.load(std::memory_order_acquire);
|
||||
while (!a.compare_exchange_strong(v, v + 1,
|
||||
std::memory_order_acq_rel,
|
||||
std::memory_order_acquire)) {
|
||||
v = a.exchange(v - 1);
|
||||
}
|
||||
|
||||
a.store(v + 1, std::memory_order_release);
|
||||
}
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
void *ptr = (void*)0xffffffc0; // any random pointer
|
||||
test(*reinterpret_cast<std::atomic<std::int64_t> *>(ptr));
|
||||
return 0;
|
||||
}
|
3
config.tests/common/atomic64/atomic64.pro
Normal file
3
config.tests/common/atomic64/atomic64.pro
Normal file
@ -0,0 +1,3 @@
|
||||
SOURCES = atomic64.cpp
|
||||
CONFIG += c++11 console
|
||||
CONFIG -= qt
|
20
configure
vendored
20
configure
vendored
@ -2,7 +2,7 @@
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2015 The Qt Company Ltd.
|
||||
## Copyright (C) 2013 Intel Corporation.
|
||||
## Copyright (C) 2015 Intel Corporation.
|
||||
## Contact: http://www.qt.io/licensing/
|
||||
##
|
||||
## This file is the build configuration utility of the Qt Toolkit.
|
||||
@ -661,6 +661,7 @@ CFG_SYSTEM_PROXIES=no
|
||||
CFG_ANDROID_STYLE_ASSETS=yes
|
||||
CFG_GSTREAMER=auto
|
||||
CFG_GSTREAMER_VERSION=""
|
||||
CFG_ATOMIC64=auto
|
||||
|
||||
# Target architecture
|
||||
CFG_ARCH=
|
||||
@ -4328,6 +4329,15 @@ if [ "$CFG_CXX11" != "no" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect whether 64-bit std::atomic works -- some 32-bit platforms require extra library support
|
||||
if compileTest common/atomic64 "64-bit std::atomic"; then
|
||||
CFG_ATOMIC64=yes
|
||||
elif compileTest common/atomic64 "64-bit std::atomic in -latomic" -latomic; then
|
||||
CFG_ATOMIC64=libatomic
|
||||
else
|
||||
CFG_ATOMIC64=no
|
||||
fi
|
||||
|
||||
# detect sse2 support
|
||||
if [ "${CFG_SSE2}" = "auto" ]; then
|
||||
if compileTest common/sse2 "sse2"; then
|
||||
@ -6016,6 +6026,10 @@ fi
|
||||
|
||||
[ "$CFG_CXX11" = "yes" ] && QT_CONFIG="$QT_CONFIG c++11"
|
||||
|
||||
if [ "$CFG_ATOMIC64" = "libatomic" ]; then
|
||||
QMAKE_CONFIG="$QMAKE_CONFIG atomic64-libatomic"
|
||||
fi
|
||||
|
||||
if [ "$CFG_SILENT" = "yes" ]; then
|
||||
QMAKE_CONFIG="$QMAKE_CONFIG silent"
|
||||
fi
|
||||
@ -6567,6 +6581,10 @@ else
|
||||
echo "#define QT_POINTER_SIZE $?" >>"$outpath/src/corelib/global/qconfig.h.new"
|
||||
fi
|
||||
|
||||
if [ "$CFG_ATOMIC64" = "no" ]; then
|
||||
echo "#define QT_NO_STD_ATOMIC64" >> "$outpath/src/corelib/global/qconfig.h.new"
|
||||
fi
|
||||
|
||||
#REDUCE_RELOCATIONS is a elf/unix only thing, so not in windows configure.exe
|
||||
if [ "$CFG_REDUCE_RELOCATIONS" = "yes" ]; then
|
||||
echo "#define QT_REDUCE_RELOCATIONS" >>"$outpath/src/corelib/global/qconfig.h.new"
|
||||
|
@ -10,6 +10,8 @@ HEADERS += \
|
||||
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
|
||||
|
@ -78,11 +78,13 @@ template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
|
||||
#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
|
||||
#ifndef QT_NO_STD_ATOMIC64
|
||||
# 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
|
||||
#endif
|
||||
|
||||
template <typename X> struct QAtomicOps
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Copyright (C) 2014 Intel Corporation
|
||||
** Copyright (C) 2015 Intel Corporation
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
@ -192,6 +192,7 @@ Configure::Configure(int& argc, char** argv)
|
||||
dictionary[ "SYSTEM_PROXIES" ] = "no";
|
||||
dictionary[ "WERROR" ] = "auto";
|
||||
dictionary[ "QREAL" ] = "double";
|
||||
dictionary[ "ATOMIC64" ] = "auto";
|
||||
|
||||
//Only used when cross compiling.
|
||||
dictionary[ "QT_INSTALL_SETTINGS" ] = "/etc/xdg";
|
||||
@ -2195,6 +2196,12 @@ bool Configure::checkAvailability(const QString &part)
|
||||
else if (part == "OBJCOPY")
|
||||
available = tryCompileProject("unix/objcopy");
|
||||
|
||||
else if (part == "ATOMIC64")
|
||||
available = tryCompileProject("common/atomic64");
|
||||
|
||||
else if (part == "ATOMIC64-LIBATOMIC")
|
||||
available = tryCompileProject("common/atomic64", "LIBS+=-latomic");
|
||||
|
||||
else if (part == "ZLIB")
|
||||
available = findFile("zlib.h");
|
||||
|
||||
@ -2343,6 +2350,10 @@ void Configure::autoDetection()
|
||||
dictionary["C++11"] = tryCompileProject("common/c++11") ? "yes" : "no";
|
||||
}
|
||||
|
||||
if (dictionary["ATOMIC64"] == "auto")
|
||||
dictionary["ATOMIC64"] = checkAvailability("ATOMIC64") ? "yes" :
|
||||
checkAvailability("ATOMIC64-LIBATOMIC") ? "libatomic" : "no";
|
||||
|
||||
// Style detection
|
||||
if (dictionary["STYLE_WINDOWSXP"] == "auto")
|
||||
dictionary["STYLE_WINDOWSXP"] = checkAvailability("STYLE_WINDOWSXP") ? defaultTo("STYLE_WINDOWSXP") : "no";
|
||||
@ -2862,6 +2873,9 @@ void Configure::generateOutputVars()
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary["ATOMIC64"] == "libatomic")
|
||||
qmakeConfig += "atomic64-libatomic";
|
||||
|
||||
if (dictionary[ "ACCESSIBILITY" ] == "yes")
|
||||
qtConfig += "accessibility";
|
||||
|
||||
@ -3661,6 +3675,7 @@ void Configure::generateConfigfiles()
|
||||
if (dictionary["QT_GLIB"] == "no") qconfigList += "QT_NO_GLIB";
|
||||
if (dictionary["QT_INOTIFY"] == "no") qconfigList += "QT_NO_INOTIFY";
|
||||
if (dictionary["QT_EVENTFD"] == "no") qconfigList += "QT_NO_EVENTFD";
|
||||
if (dictionary["ATOMIC64"] == "no") qconfigList += "QT_NO_STD_ATOMIC64";
|
||||
|
||||
if (dictionary["REDUCE_EXPORTS"] == "yes") qconfigList += "QT_VISIBILITY_AVAILABLE";
|
||||
if (dictionary["REDUCE_RELOCATIONS"] == "yes") qconfigList += "QT_REDUCE_RELOCATIONS";
|
||||
|
Loading…
x
Reference in New Issue
Block a user