mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 04:24:37 +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/support.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
// Required by `__cpuidex()` and `_xgetbv()`.
|
||||
#if ASMJIT_ARCH_X86
|
||||
#if defined(_MSC_VER)
|
||||
@@ -1969,13 +1971,13 @@ static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
|
||||
// CpuInfo - Detect - Host
|
||||
// =======================
|
||||
|
||||
static uint32_t cpuInfoInitialized;
|
||||
static CpuInfo cpuInfoGlobal(Globals::NoInit);
|
||||
|
||||
const CpuInfo& CpuInfo::host() noexcept {
|
||||
// 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) {
|
||||
static std::atomic<uint32_t> cpuInfoInitialized;
|
||||
static CpuInfo cpuInfoGlobal(Globals::NoInit);
|
||||
|
||||
// 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;
|
||||
|
||||
cpuInfoLocal._arch = Arch::kHost;
|
||||
@@ -1989,7 +1991,7 @@ const CpuInfo& CpuInfo::host() noexcept {
|
||||
|
||||
cpuInfoLocal._hwThreadCount = detectHWThreadCount();
|
||||
cpuInfoGlobal = cpuInfoLocal;
|
||||
cpuInfoInitialized = 1;
|
||||
cpuInfoInitialized.store(1, std::memory_order_seq_cst);
|
||||
}
|
||||
|
||||
return cpuInfoGlobal;
|
||||
|
||||
@@ -22,11 +22,6 @@ ASMJIT_BEGIN_NAMESPACE
|
||||
//! Each feature is represented by a single bit in an embedded bit array.
|
||||
class CpuFeatures {
|
||||
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
|
||||
//! \{
|
||||
|
||||
@@ -37,6 +32,13 @@ public:
|
||||
};
|
||||
//! \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
|
||||
@@ -48,7 +50,7 @@ public:
|
||||
//! \{
|
||||
|
||||
//! Data bits.
|
||||
Support::Array<BitWord, kNumBitWords> _bits;
|
||||
Bits _bits;
|
||||
|
||||
//! \}
|
||||
|
||||
@@ -178,8 +180,7 @@ public:
|
||||
#endif // !ASMJIT_NO_DEPRECATED
|
||||
|
||||
//! \}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
//! X86 specific features data.
|
||||
struct X86 : public Data {
|
||||
@@ -948,6 +949,7 @@ public:
|
||||
|
||||
ASMJIT_INLINE_NODEBUG CpuFeatures() noexcept {}
|
||||
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 {}
|
||||
|
||||
//! \}
|
||||
|
||||
Reference in New Issue
Block a user