From 1f8ead65730a2ed3f7fa721ec48dbf20de02cca7 Mon Sep 17 00:00:00 2001 From: Ilya Orlov Date: Thu, 24 May 2018 12:49:20 +0300 Subject: [PATCH] xrCore: detect cpuid feature from q4a --- src/xrCore/cpuid.cpp | 55 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/xrCore/cpuid.cpp b/src/xrCore/cpuid.cpp index 93333c8942f..c371ea5c927 100644 --- a/src/xrCore/cpuid.cpp +++ b/src/xrCore/cpuid.cpp @@ -19,7 +19,34 @@ unsgined int query_processor_info(processor_info* pinfo) #undef _CPUID_DEBUG -#if defined(WINDOWS) +void nativeCpuId(int regs[4], int i) +{ +#ifdef WINDOWS + __cpuid((int *)regs, (int)i); +#elif defined(LINUX) && defined(GCC) + __cpuid((int)i, (int *)regs); +#elif defined(LINUX) + asm volatile("cpuid" : + "=eax" (regs[0]), + "=ebx" (regs[1]), + "=ecx" (regs[2]), + "=edx" (regs[3]) + : "eax" (i)); +#else +#error Cpuid is not implemented +#endif +} + +#ifndef WINDOWS +#include + +void __cpuidex(int regs[4], int i, int j) +{ + nativeCpuId(regs, i); +} +#endif + +#ifdef WINDOWS DWORD countSetBits(ULONG_PTR bitMask) { DWORD LSHIFT = sizeof(ULONG_PTR) * 8 - 1; @@ -41,7 +68,6 @@ unsigned int query_processor_info(processor_info* pinfo) { ZeroMemory(pinfo, sizeof(processor_info)); -#if defined(WINDOWS) std::bitset<32> f_1_ECX; std::bitset<32> f_1_EDX; /*std::bitset<32> f_7_EBX; @@ -52,7 +78,7 @@ unsigned int query_processor_info(processor_info* pinfo) xr_vector> data; std::array cpui; - __cpuid(cpui.data(), 0); + nativeCpuId(cpui.data(), 0); const int nIds = cpui[0]; for (int i = 0; i <= nIds; ++i) @@ -83,7 +109,7 @@ unsigned int query_processor_info(processor_info* pinfo) f_7_ECX = data[7][2]; }*/ - __cpuid(cpui.data(), 0x80000000); + nativeCpuId(cpui.data(), 0x80000000); const int nExIds_ = cpui[0]; data.clear(); @@ -120,7 +146,7 @@ unsigned int query_processor_info(processor_info* pinfo) if (f_1_ECX[19]) pinfo->features |= static_cast(CpuFeature::Sse41); if (f_1_ECX[20]) pinfo->features |= static_cast(CpuFeature::Sse42); - __cpuid(cpui.data(), 1); + nativeCpuId(cpui.data(), 1); const bool hasMWait = (cpui[2] & 0x8) > 0; if (hasMWait) pinfo->features |= static_cast(CpuFeature::MWait); @@ -130,9 +156,21 @@ unsigned int query_processor_info(processor_info* pinfo) pinfo->stepping = cpui[0] & 0xf; // Calculate available processors +#ifdef WINDOWS ULONG_PTR pa_mask_save, sa_mask_stub = 0; GetProcessAffinityMask(GetCurrentProcess(), &pa_mask_save, &sa_mask_stub); +#elif defined(LINUX) + unsigned int pa_mask_save = 0; + cpu_set_t my_set; + CPU_ZERO(&my_set); + sched_getaffinity(0, sizeof(cpu_set_t), &my_set); + pa_mask_save = CPU_COUNT(&my_set); +#else +#warning "No Function to obtain process affinity" + unsigned int pa_mask_save = 0; +#endif // WINDOWS +#ifdef WINDOWS DWORD returnedLength = 0; DWORD byteOffset = 0; GetLogicalProcessorInformation(nullptr, &returnedLength); @@ -162,6 +200,12 @@ unsigned int query_processor_info(processor_info* pinfo) byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ptr++; } +#elif defined(LINUX) + int logicalProcessorCount = std::thread::hardware_concurrency(); + + int processorCoreCount = sysconf(_SC_NPROCESSORS_ONLN); +#endif + if (logicalProcessorCount != processorCoreCount) pinfo->features |= static_cast(CpuFeature::HT); @@ -169,7 +213,6 @@ unsigned int query_processor_info(processor_info* pinfo) pinfo->n_threads = logicalProcessorCount; pinfo->affinity_mask = pa_mask_save; pinfo->n_cores = processorCoreCount; -#endif return pinfo->features; }