From fb123f93f9f5ce42c8e5785d2f8e0edaf951740e Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Wed, 26 Mar 2014 19:21:20 +0000 Subject: Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2. --- src/VBox/Runtime/r3/win/mp-win.cpp | 69 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'src/VBox/Runtime/r3/win/mp-win.cpp') diff --git a/src/VBox/Runtime/r3/win/mp-win.cpp b/src/VBox/Runtime/r3/win/mp-win.cpp index fed1152b..dce41d19 100644 --- a/src/VBox/Runtime/r3/win/mp-win.cpp +++ b/src/VBox/Runtime/r3/win/mp-win.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -30,9 +30,14 @@ *******************************************************************************/ #define LOG_GROUP RTLOGGROUP_SYSTEM #include + #include -#include +#include "internal/iprt.h" + #include +#include +#include +#include AssertCompile(MAXIMUM_PROCESSORS <= RTCPUSET_MAX_CPUS); @@ -91,6 +96,59 @@ RTDECL(RTCPUID) RTMpGetCount(void) } +RTDECL(RTCPUID) RTMpGetCoreCount(void) +{ + /* + * Resolve the API dynamically (one try) as it requires XP w/ sp3 or later. + */ + typedef BOOL (WINAPI *PFNGETLOGICALPROCINFO)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); + static PFNGETLOGICALPROCINFO s_pfnGetLogicalProcInfo = (PFNGETLOGICALPROCINFO)~(uintptr_t)0; + if (s_pfnGetLogicalProcInfo == (PFNGETLOGICALPROCINFO)~(uintptr_t)0) + s_pfnGetLogicalProcInfo = (PFNGETLOGICALPROCINFO)RTLdrGetSystemSymbol("kernel32.dll", "GetLogicalProcessorInformation"); + + if (s_pfnGetLogicalProcInfo) + { + /* + * Query the information. This unfortunately requires a buffer, so we + * start with a guess and let windows advice us if it's too small. + */ + DWORD cbSysProcInfo = _4K; + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION paSysInfo = NULL; + BOOL fRc = FALSE; + do + { + cbSysProcInfo = RT_ALIGN_32(cbSysProcInfo, 256); + void *pv = RTMemRealloc(paSysInfo, cbSysProcInfo); + if (!pv) + break; + paSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)pv; + fRc = s_pfnGetLogicalProcInfo(paSysInfo, &cbSysProcInfo); + } while (!fRc && GetLastError() == ERROR_INSUFFICIENT_BUFFER); + if (fRc) + { + /* + * Parse the result. + */ + uint32_t cCores = 0; + uint32_t i = cbSysProcInfo / sizeof(paSysInfo[0]); + while (i-- > 0) + if (paSysInfo[i].Relationship == RelationProcessorCore) + cCores++; + + RTMemFree(paSysInfo); + Assert(cCores > 0); + return cCores; + } + + RTMemFree(paSysInfo); + } + + /* If we don't have the necessary API or if it failed, return the same + value as the generic implementation. */ + return RTMpGetCount(); +} + + RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet) { SYSTEM_INFO SysInfo; @@ -107,3 +165,10 @@ RTDECL(RTCPUID) RTMpGetOnlineCount(void) return RTCpuSetCount(&Set); } + +RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void) +{ + /** @todo this isn't entirely correct. */ + return RTMpGetCoreCount(); +} + -- cgit v1.2.1