mp-win.cpp revision bc7e0e9e31c9f674854827db723e8ce595aa7d87
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync/* $Id$ */
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync/** @file
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * IPRT - Multiprocessor, Windows.
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync */
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2006-2011 Oracle Corporation
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync *
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * available from http://www.virtualbox.org. This file is free software;
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync *
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * The contents of this file may alternatively be used under the terms
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * of the Common Development and Distribution License Version 1.0
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * VirtualBox OSE distribution, in which case the provisions of the
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync * CDDL are applicable instead of those of the GPL.
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync *
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync * You may elect to license modified versions of this file under the
1dc25926f76c463686b66fb6adec583eef0717advboxsync * terms and conditions of either the GPL or the CDDL or both.
1dc25926f76c463686b66fb6adec583eef0717advboxsync */
1dc25926f76c463686b66fb6adec583eef0717advboxsync
1dc25926f76c463686b66fb6adec583eef0717advboxsync
1dc25926f76c463686b66fb6adec583eef0717advboxsync/*******************************************************************************
1dc25926f76c463686b66fb6adec583eef0717advboxsync* Header Files *
1dc25926f76c463686b66fb6adec583eef0717advboxsync*******************************************************************************/
1dc25926f76c463686b66fb6adec583eef0717advboxsync#define LOG_GROUP RTLOGGROUP_SYSTEM
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync#include <Windows.h>
1dc25926f76c463686b66fb6adec583eef0717advboxsync#include <iprt/mp.h>
1dc25926f76c463686b66fb6adec583eef0717advboxsync#include <iprt/cpuset.h>
1dc25926f76c463686b66fb6adec583eef0717advboxsync#include <iprt/assert.h>
1dc25926f76c463686b66fb6adec583eef0717advboxsync#include <iprt/mem.h>
209c11e4b5dbb310116c99a42d773163928e002bvboxsync
1dc25926f76c463686b66fb6adec583eef0717advboxsync
1dc25926f76c463686b66fb6adec583eef0717advboxsyncAssertCompile(MAXIMUM_PROCESSORS <= RTCPUSET_MAX_CPUS);
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync
b2def6ea46868a11f7fd2857874e46c51932223avboxsync
b2def6ea46868a11f7fd2857874e46c51932223avboxsync/** @todo RTmpCpuId(). */
b2def6ea46868a11f7fd2857874e46c51932223avboxsync
b2def6ea46868a11f7fd2857874e46c51932223avboxsyncRTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
b2def6ea46868a11f7fd2857874e46c51932223avboxsync{
e4d7b580d72e968d3753363ab36e196a968c1947vboxsync return idCpu < MAXIMUM_PROCESSORS ? idCpu : -1;
b2def6ea46868a11f7fd2857874e46c51932223avboxsync}
b2def6ea46868a11f7fd2857874e46c51932223avboxsync
e4d7b580d72e968d3753363ab36e196a968c1947vboxsync
e4d7b580d72e968d3753363ab36e196a968c1947vboxsyncRTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
b2def6ea46868a11f7fd2857874e46c51932223avboxsync{
e4d7b580d72e968d3753363ab36e196a968c1947vboxsync return (unsigned)iCpu < MAXIMUM_PROCESSORS ? iCpu : NIL_RTCPUID;
1084dfee3c44a35cbe9aef69158474a913a3e0d9vboxsync}
e4d7b580d72e968d3753363ab36e196a968c1947vboxsync
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync
9347f1987dfb760943aba5a9ef094c6066901be3vboxsyncRTDECL(RTCPUID) RTMpGetMaxCpuId(void)
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync{
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync return MAXIMUM_PROCESSORS - 1;
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync}
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync
9347f1987dfb760943aba5a9ef094c6066901be3vboxsync
b2def6ea46868a11f7fd2857874e46c51932223avboxsyncRTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
b2def6ea46868a11f7fd2857874e46c51932223avboxsync{
b2def6ea46868a11f7fd2857874e46c51932223avboxsync RTCPUSET Set;
b2def6ea46868a11f7fd2857874e46c51932223avboxsync return RTCpuSetIsMember(RTMpGetOnlineSet(&Set), idCpu);
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync}
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsyncRTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync{
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync RTCPUSET Set;
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync return RTCpuSetIsMember(RTMpGetSet(&Set), idCpu);
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync}
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsyncRTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync{
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync RTCPUID idCpu = RTMpGetCount();
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync RTCpuSetEmpty(pSet);
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync while (idCpu-- > 0)
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync RTCpuSetAdd(pSet, idCpu);
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync return pSet;
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync}
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsyncRTDECL(RTCPUID) RTMpGetCount(void)
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync{
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync SYSTEM_INFO SysInfo;
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync GetSystemInfo(&SysInfo);
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync Assert((RTCPUID)SysInfo.dwNumberOfProcessors == SysInfo.dwNumberOfProcessors);
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync return SysInfo.dwNumberOfProcessors;
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync}
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsyncRTDECL(RTCPUID) RTMpGetCoreCount(void)
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync{
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync BOOL (WINAPI *pfnGetLogicalProcInfo)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync pfnGetLogicalProcInfo = (BOOL (WINAPI *)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD))
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "GetLogicalProcessorInformation");
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync /* 0 represents an error condition. We cannot return VERR* error codes as caller expects a
a448d0dfcede5c742c35e4aee5f9848a4a61bf18vboxsync * unsigned value of core count.*/
1dc25926f76c463686b66fb6adec583eef0717advboxsync if (!pfnGetLogicalProcInfo)
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync return 0;
3cc114d9c84cf4a1e3b5225e81527614c30f1d83vboxsync
3cc114d9c84cf4a1e3b5225e81527614c30f1d83vboxsync PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pSysInfo = NULL;
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync DWORD cbSysProcInfo = 0;
3cc114d9c84cf4a1e3b5225e81527614c30f1d83vboxsync BOOL fRc = pfnGetLogicalProcInfo(pSysInfo, &cbSysProcInfo);
1dc25926f76c463686b66fb6adec583eef0717advboxsync if (!fRc)
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync {
1dc25926f76c463686b66fb6adec583eef0717advboxsync if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync pSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)RTMemAlloc(cbSysProcInfo);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync }
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync
3cc114d9c84cf4a1e3b5225e81527614c30f1d83vboxsync RTCPUID cCores = 0;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync if (pSysInfo)
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync {
3cc114d9c84cf4a1e3b5225e81527614c30f1d83vboxsync fRc = pfnGetLogicalProcInfo(pSysInfo, &cbSysProcInfo);
1dc25926f76c463686b66fb6adec583eef0717advboxsync if (fRc)
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync {
1dc25926f76c463686b66fb6adec583eef0717advboxsync PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pSysInfoTmp = pSysInfo;
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync size_t offs = 0;
1d5596b941d86a014c20420b73ad7be2de35cf9dvboxsync while (offs + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= cbSysProcInfo)
1d5596b941d86a014c20420b73ad7be2de35cf9dvboxsync {
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync switch (pSysInfoTmp->Relationship)
1d5596b941d86a014c20420b73ad7be2de35cf9dvboxsync {
1d5596b941d86a014c20420b73ad7be2de35cf9dvboxsync case RelationProcessorCore:
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync cCores++;
1d5596b941d86a014c20420b73ad7be2de35cf9dvboxsync break;
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync case RelationCache:
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync case RelationNumaNode:
b2def6ea46868a11f7fd2857874e46c51932223avboxsync case RelationProcessorPackage:
b2def6ea46868a11f7fd2857874e46c51932223avboxsync default:
b2def6ea46868a11f7fd2857874e46c51932223avboxsync ;
3cc114d9c84cf4a1e3b5225e81527614c30f1d83vboxsync }
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync offs += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync pSysInfoTmp++;
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync }
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync }
3cc114d9c84cf4a1e3b5225e81527614c30f1d83vboxsync RTMemFree(pSysInfo);
1dc25926f76c463686b66fb6adec583eef0717advboxsync }
1dc25926f76c463686b66fb6adec583eef0717advboxsync return cCores;
1dc25926f76c463686b66fb6adec583eef0717advboxsync}
5e31c5b77713d7c61de5f65f1c3d057dddaa27f3vboxsync
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsyncRTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync{
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync SYSTEM_INFO SysInfo;
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync GetSystemInfo(&SysInfo);
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync/** @todo port to W2K8 / W7 w/ > 64 CPUs & grouping. */
1205f5a22a14de7b9cf3055d6f914eac690c1715vboxsync return RTCpuSetFromU64(pSet, SysInfo.dwActiveProcessorMask);
}
RTDECL(RTCPUID) RTMpGetOnlineCount(void)
{
RTCPUSET Set;
RTMpGetOnlineSet(&Set);
return RTCpuSetCount(&Set);
}