From 1dbd731d2426059a0d41e612458ddd265920ec8c Mon Sep 17 00:00:00 2001 From: Aleksey Komarov Date: Sat, 19 May 2018 12:55:42 +0300 Subject: [PATCH] add linux compatibility level to xrCore/cpuid.cpp. Some parts taken from 0xBADEAFFE/xray-16, some from stackoverflow.com --- src/xrCore/cpuid.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/src/xrCore/cpuid.cpp b/src/xrCore/cpuid.cpp index c3b2756cf6f..4b97c08f380 100644 --- a/src/xrCore/cpuid.cpp +++ b/src/xrCore/cpuid.cpp @@ -19,6 +19,33 @@ unsgined int query_processor_info(processor_info* pinfo) #undef _CPUID_DEBUG +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 + DWORD countSetBits(ULONG_PTR bitMask) { DWORD LSHIFT = sizeof(ULONG_PTR) * 8 - 1; @@ -49,7 +76,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) @@ -80,7 +107,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(); @@ -117,7 +144,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); @@ -127,8 +154,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; @@ -160,6 +200,34 @@ unsigned int query_processor_info(processor_info* pinfo) ptr++; } +#else // WINDOWS + + int logicalProcessorCount = std::thread::hardware_concurrency(); + + //not sure about processorCoreCount - is it really cores or threads + //https://stackoverflow.com/questions/150355/programmatically-find-the-number-of-cores-on-a-machine + int processorCoreCount = sysconf(_SC_NPROCESSORS_ONLN); + + //2nd implementation + // + //#include + //// Allocate, initialize, and perform topology detection + //hwloc_topology_t topology; + //hwloc_topology_init(&topology); + //hwloc_topology_load(topology); + // + //// Try to get the number of CPU cores from topology + //int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_CORE); + //int processorCoreCount = hwloc_get_nbobjs_by_depth(topology, depth); + // + //// Destroy topology object and return + //hwloc_topology_destroy(topology); + + //3rd another implementation + //https://stackoverflow.com/questions/2901694/programmatically-detect-number-of-physical-processors-cores-or-if-hyper-threadin + +#endif // WINDOWS + if (logicalProcessorCount != processorCoreCount) pinfo->features |= static_cast(CpuFeature::HT); // All logical processors