From 41a9dfefb68fb2337a250c97c3c24b28d8ab686f Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Wed, 29 Mar 2017 16:44:21 -0400 Subject: [PATCH] SystemInformation: Fix dynamic loader failure on WinXP SP2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Load the `GetLogicalProcessorInformation` function address at runtime. If it is not available use a fallback implementation. Co-Author: Nicolás Bértolo <nicolasbertolo@gmail.com> Issue: cmake/cmake#16751 --- SystemInformation.cxx | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/SystemInformation.cxx b/SystemInformation.cxx index 93312e9d..70f1a434 100644 --- a/SystemInformation.cxx +++ b/SystemInformation.cxx @@ -4341,18 +4341,35 @@ unsigned char SystemInformationImplementation::GetAPICId() void SystemInformationImplementation::CPUCountWindows() { #if defined(_WIN32) - std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> ProcInfo; this->NumberOfPhysicalCPU = 0; this->NumberOfLogicalCPU = 0; + typedef BOOL(WINAPI * GetLogicalProcessorInformationType)( + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); + static GetLogicalProcessorInformationType pGetLogicalProcessorInformation = + (GetLogicalProcessorInformationType)GetProcAddress( + GetModuleHandleW(L"kernel32"), "GetLogicalProcessorInformation"); + + if (!pGetLogicalProcessorInformation) { + // Fallback to approximate implementation on ancient Windows versions. + SYSTEM_INFO info; + ZeroMemory(&info, sizeof(info)); + GetSystemInfo(&info); + this->NumberOfPhysicalCPU = + static_cast<unsigned int>(info.dwNumberOfProcessors); + this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; + return; + } + + std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> ProcInfo; { DWORD Length = 0; - DWORD rc = GetLogicalProcessorInformation(NULL, &Length); + DWORD rc = pGetLogicalProcessorInformation(NULL, &Length); assert(FALSE == rc); (void)rc; // Silence unused variable warning in Borland C++ 5.81 assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER); ProcInfo.resize(Length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); - rc = GetLogicalProcessorInformation(&ProcInfo[0], &Length); + rc = pGetLogicalProcessorInformation(&ProcInfo[0], &Length); assert(rc != FALSE); (void)rc; // Silence unused variable warning in Borland C++ 5.81 } -- GitLab