diff --git a/src/corelib/global/qsimd.cpp b/src/corelib/global/qsimd.cpp index 72fcf630948..d2a06860978 100644 --- a/src/corelib/global/qsimd.cpp +++ b/src/corelib/global/qsimd.cpp @@ -584,10 +584,10 @@ static inline uint detectProcessorFeatures() static const quint64 minFeature = qCompilerCpuFeatures; static constexpr auto SimdInitialized = QCpuFeatureType(1) << (sizeof(QCpuFeatureType) * 8 - 1); -QBasicAtomicInteger qt_cpu_features[1] = { 0 }; +Q_ATOMIC(QCpuFeatureType) QT_MANGLE_NAMESPACE(qt_cpu_features)[1] = { 0 }; QT_FUNCTION_TARGET_BASELINE -quint64 qDetectCpuFeatures() +uint64_t QT_MANGLE_NAMESPACE(qDetectCpuFeatures)() { auto minFeatureTest = minFeature; #if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_64) @@ -595,7 +595,7 @@ quint64 qDetectCpuFeatures() // automatically by compilers, we can just add runtime check. minFeatureTest &= ~(CpuFeatureAES|CpuFeatureCRC32); #endif - quint64 f = detectProcessorFeatures(); + QCpuFeatureType f = detectProcessorFeatures(); // Intentionally NOT qgetenv (this code runs too early) if (char *disable = getenv("QT_NO_CPU_FEATURE"); disable && *disable) { @@ -632,7 +632,8 @@ quint64 qDetectCpuFeatures() } assert((f & SimdInitialized) == 0); - qt_cpu_features[0].storeRelease(f | SimdInitialized); + f |= SimdInitialized; + std::atomic_store_explicit(QT_MANGLE_NAMESPACE(qt_cpu_features), f, std::memory_order_relaxed); return f; } @@ -791,7 +792,7 @@ static bool checkRdrndWorks() noexcept { return false; } namespace { struct QSimdInitializer { - inline QSimdInitializer() { qDetectCpuFeatures(); } + inline QSimdInitializer() { QT_MANGLE_NAMESPACE(qDetectCpuFeatures)(); } }; } diff --git a/src/corelib/global/qsimd_p.h b/src/corelib/global/qsimd_p.h index ad769ee7a65..ccb995588b6 100644 --- a/src/corelib/global/qsimd_p.h +++ b/src/corelib/global/qsimd_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2021 The Qt Company Ltd. +** Copyright (C) 2022 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -253,28 +253,6 @@ asm( defined(__FMA__) && defined(__LZCNT__) && defined(__RDRND__) # define __haswell__ 1 # endif - -QT_BEGIN_NAMESPACE -static const quint64 qCompilerCpuFeatures = _compilerCpuFeatures; - -// This constant does not include all CPU features found in a Haswell, only -// those that we'd have optimized code for. -// Note: must use Q_CONSTEXPR here, as this file may be compiled in C mode. -static const quint64 CpuFeatureArchHaswell = 0 - | CpuFeatureSSE2 - | CpuFeatureSSE3 - | CpuFeatureSSSE3 - | CpuFeatureSSE4_1 - | CpuFeatureSSE4_2 - | CpuFeatureFMA - | CpuFeaturePOPCNT - | CpuFeatureAVX - | CpuFeatureF16C - | CpuFeatureAVX2 - | CpuFeatureBMI - | CpuFeatureBMI2; -QT_END_NAMESPACE - #endif /* Q_PROCESSOR_X86 */ // NEON intrinsics @@ -329,12 +307,6 @@ inline uint8_t vaddv_u8(uint8x8_t v8) #endif #endif - -#ifdef __cplusplus -#include - -QT_BEGIN_NAMESPACE - #ifndef Q_PROCESSOR_X86 enum CPUFeatures { #if defined(Q_PROCESSOR_ARM) @@ -368,29 +340,35 @@ static const quint64 qCompilerCpuFeatures = 0 ; #endif +#ifdef __cplusplus +# include +# define Q_ATOMIC(T) std::atomic +QT_BEGIN_NAMESPACE +using std::atomic_load_explicit; +static constexpr auto memory_order_relaxed = std::memory_order_relaxed; +extern "C" { +#else +# include +# include +# define Q_ATOMIC(T) _Atomic(T) +#endif + #ifdef Q_PROCESSOR_X86 -using QCpuFeatureType = quint64; +typedef uint64_t QCpuFeatureType; +static const QCpuFeatureType qCompilerCpuFeatures = _compilerCpuFeatures; +static const QCpuFeatureType CpuFeatureArchHaswell = cpu_haswell; #else -using QCpuFeatureType = unsigned; +typedef unsigned QCpuFeatureType; #endif -extern Q_CORE_EXPORT QBasicAtomicInteger qt_cpu_features[1]; -Q_CORE_EXPORT quint64 qDetectCpuFeatures(); +extern Q_CORE_EXPORT Q_ATOMIC(QCpuFeatureType) QT_MANGLE_NAMESPACE(qt_cpu_features)[1]; +Q_CORE_EXPORT uint64_t QT_MANGLE_NAMESPACE(qDetectCpuFeatures)(); -#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) && !defined(QT_BOOTSTRAPPED) -Q_CORE_EXPORT qsizetype qRandomCpu(void *, qsizetype) noexcept; -#else -static inline qsizetype qRandomCpu(void *, qsizetype) noexcept +static inline uint64_t qCpuFeatures() { - return 0; -} -#endif - -static inline quint64 qCpuFeatures() -{ - quint64 features = qt_cpu_features[0].loadRelaxed(); - if constexpr (!QT_SUPPORTS_INIT_PRIORITY) { + quint64 features = atomic_load_explicit(QT_MANGLE_NAMESPACE(qt_cpu_features), memory_order_relaxed); + if (!QT_SUPPORTS_INIT_PRIORITY) { if (Q_UNLIKELY(features == 0)) - features = qDetectCpuFeatures(); + features = QT_MANGLE_NAMESPACE(qDetectCpuFeatures)(); } return features; } @@ -398,6 +376,9 @@ static inline quint64 qCpuFeatures() #define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature) \ || ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature)) +#ifdef __cplusplus +} // extern "C" + # if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) && !defined(QT_BOOTSTRAPPED) Q_CORE_EXPORT qsizetype qRandomCpu(void *, qsizetype) noexcept;