diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/common_funcs.h | 4 | ||||
| -rw-r--r-- | src/common/host_memory.cpp | 6 | ||||
| -rw-r--r-- | src/common/settings.cpp | 1 | ||||
| -rw-r--r-- | src/common/x64/cpu_detect.cpp | 59 | ||||
| -rw-r--r-- | src/common/x64/cpu_detect.h | 4 |
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 @@ | |||
| 31 | 31 | ||
| 32 | #ifndef _MSC_VER | 32 | #ifndef _MSC_VER |
| 33 | 33 | ||
| 34 | #ifdef ARCHITECTURE_x86_64 | 34 | #if defined(ARCHITECTURE_x86_64) |
| 35 | #define Crash() __asm__ __volatile__("int $3") | 35 | #define Crash() __asm__ __volatile__("int $3") |
| 36 | #elif defined(ARCHITECTURE_arm64) | ||
| 37 | #define Crash() __asm__ __volatile__("brk #0") | ||
| 36 | #else | 38 | #else |
| 37 | #define Crash() exit(1) | 39 | #define Crash() exit(1) |
| 38 | #endif | 40 | #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: | |||
| 359 | } | 359 | } |
| 360 | }); | 360 | }); |
| 361 | 361 | ||
| 362 | long page_size = sysconf(_SC_PAGESIZE); | ||
| 363 | if (page_size != 0x1000) { | ||
| 364 | LOG_CRITICAL(HW_Memory, "page size {:#x} is incompatible with 4K paging", page_size); | ||
| 365 | throw std::bad_alloc{}; | ||
| 366 | } | ||
| 367 | |||
| 362 | // Backing memory initialization | 368 | // Backing memory initialization |
| 363 | #if defined(__FreeBSD__) && __FreeBSD__ < 13 | 369 | #if defined(__FreeBSD__) && __FreeBSD__ < 13 |
| 364 | // XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30 | 370 | // 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() { | |||
| 151 | ASSERT(false); | 151 | ASSERT(false); |
| 152 | info.up_scale = 1; | 152 | info.up_scale = 1; |
| 153 | info.down_shift = 0; | 153 | info.down_shift = 0; |
| 154 | break; | ||
| 154 | } | 155 | } |
| 155 | info.up_factor = static_cast<f32>(info.up_scale) / (1U << info.down_shift); | 156 | info.up_factor = static_cast<f32>(info.up_scale) / (1U << info.down_shift); |
| 156 | info.down_factor = static_cast<f32>(1U << info.down_shift) / info.up_scale; | 157 | 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 @@ | |||
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <cstring> | 6 | #include <cstring> |
| 7 | #include <fstream> | ||
| 7 | #include <iterator> | 8 | #include <iterator> |
| 9 | #include <optional> | ||
| 8 | #include <string_view> | 10 | #include <string_view> |
| 11 | #include <thread> | ||
| 12 | #include <vector> | ||
| 9 | #include "common/bit_util.h" | 13 | #include "common/bit_util.h" |
| 10 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "common/logging/log.h" | ||
| 11 | #include "common/x64/cpu_detect.h" | 16 | #include "common/x64/cpu_detect.h" |
| 12 | 17 | ||
| 18 | #ifdef _WIN32 | ||
| 19 | #include <windows.h> | ||
| 20 | #endif | ||
| 21 | |||
| 13 | #ifdef _MSC_VER | 22 | #ifdef _MSC_VER |
| 14 | #include <intrin.h> | 23 | #include <intrin.h> |
| 24 | |||
| 25 | static inline u64 xgetbv(u32 index) { | ||
| 26 | return _xgetbv(index); | ||
| 27 | } | ||
| 15 | #else | 28 | #else |
| 16 | 29 | ||
| 17 | #if defined(__DragonFly__) || defined(__FreeBSD__) | 30 | #if defined(__DragonFly__) || defined(__FreeBSD__) |
| @@ -39,12 +52,11 @@ static inline void __cpuid(int info[4], u32 function_id) { | |||
| 39 | } | 52 | } |
| 40 | 53 | ||
| 41 | #define _XCR_XFEATURE_ENABLED_MASK 0 | 54 | #define _XCR_XFEATURE_ENABLED_MASK 0 |
| 42 | static inline u64 _xgetbv(u32 index) { | 55 | static inline u64 xgetbv(u32 index) { |
| 43 | u32 eax, edx; | 56 | u32 eax, edx; |
| 44 | __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); | 57 | __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); |
| 45 | return ((u64)edx << 32) | eax; | 58 | return ((u64)edx << 32) | eax; |
| 46 | } | 59 | } |
| 47 | |||
| 48 | #endif // _MSC_VER | 60 | #endif // _MSC_VER |
| 49 | 61 | ||
| 50 | namespace Common { | 62 | namespace Common { |
| @@ -107,7 +119,7 @@ static CPUCaps Detect() { | |||
| 107 | // - Is the XSAVE bit set in CPUID? | 119 | // - Is the XSAVE bit set in CPUID? |
| 108 | // - XGETBV result has the XCR bit set. | 120 | // - XGETBV result has the XCR bit set. |
| 109 | if (Common::Bit<28>(cpu_id[2]) && Common::Bit<27>(cpu_id[2])) { | 121 | if (Common::Bit<28>(cpu_id[2]) && Common::Bit<27>(cpu_id[2])) { |
| 110 | if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) { | 122 | if ((xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) { |
| 111 | caps.avx = true; | 123 | caps.avx = true; |
| 112 | if (Common::Bit<12>(cpu_id[2])) | 124 | if (Common::Bit<12>(cpu_id[2])) |
| 113 | caps.fma = true; | 125 | caps.fma = true; |
| @@ -192,4 +204,45 @@ const CPUCaps& GetCPUCaps() { | |||
| 192 | return caps; | 204 | return caps; |
| 193 | } | 205 | } |
| 194 | 206 | ||
| 207 | std::optional<int> GetProcessorCount() { | ||
| 208 | #if defined(_WIN32) | ||
| 209 | // Get the buffer length. | ||
| 210 | DWORD length = 0; | ||
| 211 | GetLogicalProcessorInformation(nullptr, &length); | ||
| 212 | if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | ||
| 213 | LOG_ERROR(Frontend, "Failed to query core count."); | ||
| 214 | return std::nullopt; | ||
| 215 | } | ||
| 216 | std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer( | ||
| 217 | length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); | ||
| 218 | // Now query the core count. | ||
| 219 | if (!GetLogicalProcessorInformation(buffer.data(), &length)) { | ||
| 220 | LOG_ERROR(Frontend, "Failed to query core count."); | ||
| 221 | return std::nullopt; | ||
| 222 | } | ||
| 223 | return static_cast<int>( | ||
| 224 | std::count_if(buffer.cbegin(), buffer.cend(), [](const auto& proc_info) { | ||
| 225 | return proc_info.Relationship == RelationProcessorCore; | ||
| 226 | })); | ||
| 227 | #elif defined(__unix__) | ||
| 228 | const int thread_count = std::thread::hardware_concurrency(); | ||
| 229 | std::ifstream smt("/sys/devices/system/cpu/smt/active"); | ||
| 230 | char state = '0'; | ||
| 231 | if (smt) { | ||
| 232 | smt.read(&state, sizeof(state)); | ||
| 233 | } | ||
| 234 | switch (state) { | ||
| 235 | case '0': | ||
| 236 | return thread_count; | ||
| 237 | case '1': | ||
| 238 | return thread_count / 2; | ||
| 239 | default: | ||
| 240 | return std::nullopt; | ||
| 241 | } | ||
| 242 | #else | ||
| 243 | // Shame on you | ||
| 244 | return std::nullopt; | ||
| 245 | #endif | ||
| 246 | } | ||
| 247 | |||
| 195 | } // namespace Common | 248 | } // 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 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <optional> | ||
| 7 | #include <string_view> | 8 | #include <string_view> |
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | 10 | ||
| @@ -74,4 +75,7 @@ struct CPUCaps { | |||
| 74 | */ | 75 | */ |
| 75 | const CPUCaps& GetCPUCaps(); | 76 | const CPUCaps& GetCPUCaps(); |
| 76 | 77 | ||
| 78 | /// Detects CPU core count | ||
| 79 | std::optional<int> GetProcessorCount(); | ||
| 80 | |||
| 77 | } // namespace Common | 81 | } // namespace Common |