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