summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/common_funcs.h4
-rw-r--r--src/common/host_memory.cpp6
-rw-r--r--src/common/settings.cpp1
-rw-r--r--src/common/x64/cpu_detect.cpp59
-rw-r--r--src/common/x64/cpu_detect.h4
5 files changed, 70 insertions, 4 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index e1e2a90fc..0dad9338a 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -31,8 +31,10 @@
#ifndef _MSC_VER
-#ifdef ARCHITECTURE_x86_64
+#if defined(ARCHITECTURE_x86_64)
#define Crash() __asm__ __volatile__("int $3")
+#elif defined(ARCHITECTURE_arm64)
+#define Crash() __asm__ __volatile__("brk #0")
#else
#define Crash() exit(1)
#endif
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index 7f9659612..909f6cf3f 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -359,6 +359,12 @@ public:
}
});
+ long page_size = sysconf(_SC_PAGESIZE);
+ if (page_size != 0x1000) {
+ LOG_CRITICAL(HW_Memory, "page size {:#x} is incompatible with 4K paging", page_size);
+ throw std::bad_alloc{};
+ }
+
// Backing memory initialization
#if defined(__FreeBSD__) && __FreeBSD__ < 13
// XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 0a560ebb7..8173462cb 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -151,6 +151,7 @@ void UpdateRescalingInfo() {
ASSERT(false);
info.up_scale = 1;
info.down_shift = 0;
+ break;
}
info.up_factor = static_cast<f32>(info.up_scale) / (1U << info.down_shift);
info.down_factor = static_cast<f32>(1U << info.down_shift) / info.up_scale;
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index 1a27532d4..e54383a4a 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -4,14 +4,27 @@
#include <array>
#include <cstring>
+#include <fstream>
#include <iterator>
+#include <optional>
#include <string_view>
+#include <thread>
+#include <vector>
#include "common/bit_util.h"
#include "common/common_types.h"
+#include "common/logging/log.h"
#include "common/x64/cpu_detect.h"
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
#ifdef _MSC_VER
#include <intrin.h>
+
+static inline u64 xgetbv(u32 index) {
+ return _xgetbv(index);
+}
#else
#if defined(__DragonFly__) || defined(__FreeBSD__)
@@ -39,12 +52,11 @@ static inline void __cpuid(int info[4], u32 function_id) {
}
#define _XCR_XFEATURE_ENABLED_MASK 0
-static inline u64 _xgetbv(u32 index) {
+static inline u64 xgetbv(u32 index) {
u32 eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((u64)edx << 32) | eax;
}
-
#endif // _MSC_VER
namespace Common {
@@ -107,7 +119,7 @@ static CPUCaps Detect() {
// - Is the XSAVE bit set in CPUID?
// - XGETBV result has the XCR bit set.
if (Common::Bit<28>(cpu_id[2]) && Common::Bit<27>(cpu_id[2])) {
- if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) {
+ if ((xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) {
caps.avx = true;
if (Common::Bit<12>(cpu_id[2]))
caps.fma = true;
@@ -192,4 +204,45 @@ const CPUCaps& GetCPUCaps() {
return caps;
}
+std::optional<int> GetProcessorCount() {
+#if defined(_WIN32)
+ // Get the buffer length.
+ DWORD length = 0;
+ GetLogicalProcessorInformation(nullptr, &length);
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ LOG_ERROR(Frontend, "Failed to query core count.");
+ return std::nullopt;
+ }
+ std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(
+ length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
+ // Now query the core count.
+ if (!GetLogicalProcessorInformation(buffer.data(), &length)) {
+ LOG_ERROR(Frontend, "Failed to query core count.");
+ return std::nullopt;
+ }
+ return static_cast<int>(
+ std::count_if(buffer.cbegin(), buffer.cend(), [](const auto& proc_info) {
+ return proc_info.Relationship == RelationProcessorCore;
+ }));
+#elif defined(__unix__)
+ const int thread_count = std::thread::hardware_concurrency();
+ std::ifstream smt("/sys/devices/system/cpu/smt/active");
+ char state = '0';
+ if (smt) {
+ smt.read(&state, sizeof(state));
+ }
+ switch (state) {
+ case '0':
+ return thread_count;
+ case '1':
+ return thread_count / 2;
+ default:
+ return std::nullopt;
+ }
+#else
+ // Shame on you
+ return std::nullopt;
+#endif
+}
+
} // namespace Common
diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h
index 6830f3795..ca8db19d6 100644
--- a/src/common/x64/cpu_detect.h
+++ b/src/common/x64/cpu_detect.h
@@ -4,6 +4,7 @@
#pragma once
+#include <optional>
#include <string_view>
#include "common/common_types.h"
@@ -74,4 +75,7 @@ struct CPUCaps {
*/
const CPUCaps& GetCPUCaps();
+/// Detects CPU core count
+std::optional<int> GetProcessorCount();
+
} // namespace Common