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