mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 12:34:35 +03:00
Use atomics in CpuInfo::host()
The code was fine, however, some compilers may be able to optimize it and in some border cases the features returned would be all zero. This prevents such behavior.
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
#include "../core/cpuinfo.h"
|
#include "../core/cpuinfo.h"
|
||||||
#include "../core/support.h"
|
#include "../core/support.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
// Required by `__cpuidex()` and `_xgetbv()`.
|
// Required by `__cpuidex()` and `_xgetbv()`.
|
||||||
#if ASMJIT_ARCH_X86
|
#if ASMJIT_ARCH_X86
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@@ -1969,13 +1971,13 @@ static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
|
|||||||
// CpuInfo - Detect - Host
|
// CpuInfo - Detect - Host
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
static uint32_t cpuInfoInitialized;
|
|
||||||
static CpuInfo cpuInfoGlobal(Globals::NoInit);
|
|
||||||
|
|
||||||
const CpuInfo& CpuInfo::host() noexcept {
|
const CpuInfo& CpuInfo::host() noexcept {
|
||||||
// This should never cause a problem as the resulting information should always be the same.
|
static std::atomic<uint32_t> cpuInfoInitialized;
|
||||||
// In the worst case it would just be overwritten non-atomically.
|
static CpuInfo cpuInfoGlobal(Globals::NoInit);
|
||||||
if (!cpuInfoInitialized) {
|
|
||||||
|
// This should never cause a problem as the resulting information should always
|
||||||
|
// be the same. In the worst case it would just be overwritten non-atomically.
|
||||||
|
if (!cpuInfoInitialized.load(std::memory_order_relaxed)) {
|
||||||
CpuInfo cpuInfoLocal;
|
CpuInfo cpuInfoLocal;
|
||||||
|
|
||||||
cpuInfoLocal._arch = Arch::kHost;
|
cpuInfoLocal._arch = Arch::kHost;
|
||||||
@@ -1989,7 +1991,7 @@ const CpuInfo& CpuInfo::host() noexcept {
|
|||||||
|
|
||||||
cpuInfoLocal._hwThreadCount = detectHWThreadCount();
|
cpuInfoLocal._hwThreadCount = detectHWThreadCount();
|
||||||
cpuInfoGlobal = cpuInfoLocal;
|
cpuInfoGlobal = cpuInfoLocal;
|
||||||
cpuInfoInitialized = 1;
|
cpuInfoInitialized.store(1, std::memory_order_seq_cst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cpuInfoGlobal;
|
return cpuInfoGlobal;
|
||||||
|
|||||||
@@ -22,11 +22,6 @@ ASMJIT_BEGIN_NAMESPACE
|
|||||||
//! Each feature is represented by a single bit in an embedded bit array.
|
//! Each feature is represented by a single bit in an embedded bit array.
|
||||||
class CpuFeatures {
|
class CpuFeatures {
|
||||||
public:
|
public:
|
||||||
//! A word that is used to represents feature bits.
|
|
||||||
typedef Support::BitWord BitWord;
|
|
||||||
//! Iterator that can iterate all CPU features set.
|
|
||||||
typedef Support::BitVectorIterator<BitWord> Iterator;
|
|
||||||
|
|
||||||
//! \name Constants
|
//! \name Constants
|
||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
@@ -37,6 +32,13 @@ public:
|
|||||||
};
|
};
|
||||||
//! \endcond
|
//! \endcond
|
||||||
|
|
||||||
|
//! A word that is used to represents feature bits.
|
||||||
|
typedef Support::BitWord BitWord;
|
||||||
|
//! Iterator that can iterate all CPU features set.
|
||||||
|
typedef Support::BitVectorIterator<BitWord> Iterator;
|
||||||
|
|
||||||
|
typedef Support::Array<BitWord, kNumBitWords> Bits;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
//! \name Data
|
//! \name Data
|
||||||
@@ -48,7 +50,7 @@ public:
|
|||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
//! Data bits.
|
//! Data bits.
|
||||||
Support::Array<BitWord, kNumBitWords> _bits;
|
Bits _bits;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
@@ -178,8 +180,7 @@ public:
|
|||||||
#endif // !ASMJIT_NO_DEPRECATED
|
#endif // !ASMJIT_NO_DEPRECATED
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
};
|
||||||
};
|
|
||||||
|
|
||||||
//! X86 specific features data.
|
//! X86 specific features data.
|
||||||
struct X86 : public Data {
|
struct X86 : public Data {
|
||||||
@@ -948,6 +949,7 @@ public:
|
|||||||
|
|
||||||
ASMJIT_INLINE_NODEBUG CpuFeatures() noexcept {}
|
ASMJIT_INLINE_NODEBUG CpuFeatures() noexcept {}
|
||||||
ASMJIT_INLINE_NODEBUG CpuFeatures(const CpuFeatures& other) noexcept = default;
|
ASMJIT_INLINE_NODEBUG CpuFeatures(const CpuFeatures& other) noexcept = default;
|
||||||
|
ASMJIT_INLINE_NODEBUG explicit CpuFeatures(const Data& other) noexcept : _data{other._bits} {}
|
||||||
ASMJIT_INLINE_NODEBUG explicit CpuFeatures(Globals::NoInit_) noexcept {}
|
ASMJIT_INLINE_NODEBUG explicit CpuFeatures(Globals::NoInit_) noexcept {}
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|||||||
Reference in New Issue
Block a user