VirtualBox

Changeset 64220 in vbox for trunk/src


Ignore:
Timestamp:
Oct 12, 2016 12:38:06 PM (8 years ago)
Author:
vboxsync
Message:

mp-win.cpp: Implemented support for processor groups.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/mp-win.cpp

    r62592 r64220  
    3939#include <iprt/ldr.h>
    4040#include <iprt/mem.h>
    41 
    42 
    43 AssertCompile(MAXIMUM_PROCESSORS <= RTCPUSET_MAX_CPUS);
    44 
    45 
    46 /** @todo RTmpCpuId(). */
     41#include <iprt/once.h>
     42#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
     43# include <iprt/asm-amd64-x86.h>
     44#endif
     45
     46#include "internal-r3-win.h"
     47
     48
     49
     50/*********************************************************************************************************************************
     51*   Defined Constants And Macros                                                                                                 *
     52*********************************************************************************************************************************/
     53/** Initialize once. */
     54static RTONCE                                       g_MpInitOnce = RTONCE_INITIALIZER;
     55//static decltype(GetMaximumProcessorCount)          *g_pfnGetMaximumProcessorCount;
     56static decltype(GetCurrentProcessorNumber)         *g_pfnGetCurrentProcessorNumber;
     57static decltype(GetCurrentProcessorNumberEx)       *g_pfnGetCurrentProcessorNumberEx;
     58static decltype(GetLogicalProcessorInformation)    *g_pfnGetLogicalProcessorInformation;
     59static decltype(GetLogicalProcessorInformationEx)  *g_pfnGetLogicalProcessorInformationEx;
     60
     61
     62/*********************************************************************************************************************************
     63*   Global Variables                                                                                                             *
     64*********************************************************************************************************************************/
     65/** The required buffer size for getting group relations. */
     66static uint32_t     g_cbRtMpWinGrpRelBuf;
     67/** The max number of CPUs (RTMpGetCount). */
     68static uint32_t     g_cRtMpWinMaxCpus;
     69/** The max number of CPU cores (RTMpGetCoreCount). */
     70static uint32_t     g_cRtMpWinMaxCpuCores;
     71/** The max number of groups. */
     72static uint32_t     g_cRtMpWinMaxCpuGroups;
     73/** Static per group info. */
     74static struct
     75{
     76    /** The CPU ID (and CPU set index) of the first CPU in the group. */
     77    uint16_t    idFirstCpu;
     78    /** The max CPUs in the group. */
     79    uint16_t    cMaxCpus;
     80} g_aRtMpWinCpuGroups[RTCPUSET_MAX_CPUS];
     81
     82
     83/**
     84 * @callback_method_impl{FNRTONCE, Resolves dynamic imports.}
     85 */
     86static DECLCALLBACK(int32_t) rtMpWinInitOnce(void *pvUser)
     87{
     88    RT_NOREF(pvUser);
     89
     90    Assert(g_WinOsInfoEx.dwOSVersionInfoSize != 0);
     91    Assert(g_hModKernel32 != NULL);
     92
     93    /*
     94     * Resolve dynamic APIs.
     95     */
     96#define RESOLVE_API(a_szMod, a_FnName) \
     97        do { \
     98            RT_CONCAT(g_pfn,a_FnName) = (decltype(a_FnName) *)GetProcAddress(g_hModKernel32, #a_FnName); \
     99        } while (0)
     100    //RESOLVE_API("kernel32.dll", GetMaximumProcessorCount); /* Calls GetLogicalProcessorInformationEx/RelationGroup in W10. */
     101    RESOLVE_API("kernel32.dll", GetCurrentProcessorNumber);
     102    RESOLVE_API("kernel32.dll", GetCurrentProcessorNumberEx);
     103    RESOLVE_API("kernel32.dll", GetLogicalProcessorInformation);
     104    RESOLVE_API("kernel32.dll", GetLogicalProcessorInformationEx);
     105
     106    /*
     107     * Query group information, partitioning CPU IDs and CPU set
     108     * indexes (they are the same).
     109     *
     110     * We ASSUME the the GroupInfo index is the same as the group number.
     111     * We ASSUME there are no inactive groups, because otherwise it will
     112     * be difficult to tell how many possible CPUs we can have and do a
     113     * reasonable CPU ID/index partitioning.
     114     *
     115     * Note! We will die if there are too many processors!
     116     */
     117    union
     118    {
     119        SYSTEM_INFO                                 SysInfo;
     120        SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX     Info;
     121        uint8_t                                     abPaddingG[  sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)
     122                                                               + sizeof(PROCESSOR_GROUP_INFO) * RTCPUSET_MAX_CPUS];
     123        uint8_t                                     abPaddingC[  sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)
     124                                                               +   (sizeof(PROCESSOR_RELATIONSHIP) + sizeof(GROUP_AFFINITY))
     125                                                                 * RTCPUSET_MAX_CPUS];
     126    } uBuf;
     127    if (g_pfnGetLogicalProcessorInformationEx)
     128    {
     129        /* Query the information. */
     130        DWORD cbData = sizeof(uBuf);
     131        AssertFatalMsg(g_pfnGetLogicalProcessorInformationEx(RelationGroup, &uBuf.Info, &cbData) != FALSE,
     132                       ("last error = %u, cbData = %u (in %u)\n", GetLastError(), cbData, sizeof(uBuf)));
     133        AssertFatalMsg(uBuf.Info.Relationship == RelationGroup,
     134                       ("Relationship = %u, expected %u!\n", uBuf.Info.Relationship, RelationGroup));
     135        AssertFatalMsg(uBuf.Info.Group.MaximumGroupCount <= RT_ELEMENTS(g_aRtMpWinCpuGroups),
     136                       ("MaximumGroupCount is %u, we only support up to %u!\n",
     137                        uBuf.Info.Group.MaximumGroupCount, RT_ELEMENTS(g_aRtMpWinCpuGroups)));
     138
     139        AssertMsg(uBuf.Info.Group.MaximumGroupCount == uBuf.Info.Group.ActiveGroupCount, /* 2nd assumption mentioned above. */
     140                  ("%u vs %u\n", uBuf.Info.Group.MaximumGroupCount, uBuf.Info.Group.ActiveGroupCount));
     141        AssertFatal(uBuf.Info.Group.MaximumGroupCount >= uBuf.Info.Group.ActiveGroupCount);
     142
     143
     144        /* Process the active groups. */
     145        g_cRtMpWinMaxCpuGroups = uBuf.Info.Group.MaximumGroupCount;
     146        uint16_t idxCpu        = 0;
     147        uint32_t idxGroup      = 0;
     148        for (; idxGroup < uBuf.Info.Group.ActiveGroupCount; idxGroup++)
     149        {
     150            g_aRtMpWinCpuGroups[idxGroup].idFirstCpu = idxCpu;
     151            g_aRtMpWinCpuGroups[idxGroup].cMaxCpus   = uBuf.Info.Group.GroupInfo[idxGroup].MaximumProcessorCount;
     152            idxCpu += uBuf.Info.Group.GroupInfo[idxGroup].MaximumProcessorCount;
     153        }
     154
     155        /* Just in case the 2nd assumption doesn't hold true and there are inactive groups. */
     156        for (; idxGroup < uBuf.Info.Group.MaximumGroupCount; idxGroup++)
     157        {
     158            g_aRtMpWinCpuGroups[idxGroup].idFirstCpu = idxCpu;
     159            g_aRtMpWinCpuGroups[idxGroup].cMaxCpus   = RT_MAX(MAXIMUM_PROC_PER_GROUP, 64);
     160            idxCpu += RT_MAX(MAXIMUM_PROC_PER_GROUP, 64);
     161        }
     162
     163        g_cRtMpWinMaxCpus = idxCpu;
     164    }
     165    else
     166    {
     167        /* Legacy: */
     168        GetSystemInfo(&uBuf.SysInfo);
     169        g_cRtMpWinMaxCpus                   = uBuf.SysInfo.dwNumberOfProcessors;
     170        g_cRtMpWinMaxCpuGroups              = 1;
     171        g_aRtMpWinCpuGroups[0].idFirstCpu   = 0;
     172        g_aRtMpWinCpuGroups[0].cMaxCpus     = uBuf.SysInfo.dwNumberOfProcessors;
     173    }
     174
     175    AssertFatalMsg(g_cRtMpWinMaxCpus <= RTCPUSET_MAX_CPUS,
     176                   ("g_cRtMpWinMaxCpus=%u (%#x); RTCPUSET_MAX_CPUS=%u\n", g_cRtMpWinMaxCpus, g_cRtMpWinMaxCpus, RTCPUSET_MAX_CPUS));
     177
     178    g_cbRtMpWinGrpRelBuf = sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)
     179                         + (g_cRtMpWinMaxCpuGroups + 2) * sizeof(PROCESSOR_GROUP_INFO);
     180
     181    /*
     182     * Get information about cores.
     183     *
     184     * Note! This will only give us info about active processors according to
     185     *       MSDN, we'll just have to hope that CPUs aren't hotplugged after we
     186     *       initialize here (or that the API consumers doesn't care too much).
     187     */
     188    /** @todo A hot CPU plug event would be nice. */
     189    g_cRtMpWinMaxCpuCores = g_cRtMpWinMaxCpus;
     190    if (g_pfnGetLogicalProcessorInformationEx)
     191    {
     192        /* Query the information. */
     193        DWORD cbData = sizeof(uBuf);
     194        AssertFatalMsg(g_pfnGetLogicalProcessorInformationEx(RelationProcessorCore, &uBuf.Info, &cbData) != FALSE,
     195                       ("last error = %u, cbData = %u (in %u)\n", GetLastError(), cbData, sizeof(uBuf)));
     196        g_cRtMpWinMaxCpuCores = 0;
     197        for (uint32_t off = 0; off < cbData; )
     198        {
     199            SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *pCur = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)&uBuf.abPaddingG[off];
     200            AssertFatalMsg(pCur->Relationship == RelationProcessorCore,
     201                           ("off = %#x, Relationship = %u, expected %u!\n", off, pCur->Relationship, RelationProcessorCore));
     202            g_cRtMpWinMaxCpuCores++;
     203            off += pCur->Size;
     204        }
     205
     206#if ARCH_BITS == 32
     207        if (g_cRtMpWinMaxCpuCores > g_cRtMpWinMaxCpus)
     208        {
     209            /** @todo WOW64 trouble where the emulation environment has folded the high
     210             *        processor masks (63..32) into the low (31..0), hiding some
     211             *        processors from us.  Currently we don't deal with that. */
     212            g_cRtMpWinMaxCpuCores = g_cRtMpWinMaxCpus;
     213        }
     214        else
     215            AssertStmt(g_cRtMpWinMaxCpuCores > 0, g_cRtMpWinMaxCpuCores = g_cRtMpWinMaxCpus);
     216#else
     217        AssertStmt(g_cRtMpWinMaxCpuCores > 0 && g_cRtMpWinMaxCpuCores <= g_cRtMpWinMaxCpus,
     218                   g_cRtMpWinMaxCpuCores = g_cRtMpWinMaxCpus);
     219#endif
     220    }
     221    else
     222    {
     223        /*
     224         * Sadly, on XP and Server 2003, even if the API is present, it does not tell us
     225         * how many physical cores there are (any package will look like a single core).
     226         * That is worse than not using the API at all, so just skip it unless it's Vista+.
     227         */
     228        if (   g_pfnGetLogicalProcessorInformation
     229            && g_WinOsInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT
     230            && g_WinOsInfoEx.dwMajorVersion >= 6)
     231        {
     232            /* Query the info. */
     233            DWORD                                   cbSysProcInfo = _4K;
     234            PSYSTEM_LOGICAL_PROCESSOR_INFORMATION   paSysInfo = NULL;
     235            BOOL                                    fRc = FALSE;
     236            do
     237            {
     238                cbSysProcInfo = RT_ALIGN_32(cbSysProcInfo, 256);
     239                void *pv = RTMemRealloc(paSysInfo, cbSysProcInfo);
     240                if (!pv)
     241                    break;
     242                paSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)pv;
     243                fRc = g_pfnGetLogicalProcessorInformation(paSysInfo, &cbSysProcInfo);
     244            } while (!fRc && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
     245            if (fRc)
     246            {
     247                /* Count the cores in the result. */
     248                g_cRtMpWinMaxCpuCores = 0;
     249                uint32_t i = cbSysProcInfo / sizeof(paSysInfo[0]);
     250                while (i-- > 0)
     251                    if (paSysInfo[i].Relationship == RelationProcessorCore)
     252                        g_cRtMpWinMaxCpuCores++;
     253
     254                AssertStmt(g_cRtMpWinMaxCpuCores > 0 && g_cRtMpWinMaxCpuCores <= g_cRtMpWinMaxCpus,
     255                           g_cRtMpWinMaxCpuCores = g_cRtMpWinMaxCpus);
     256            }
     257            RTMemFree(paSysInfo);
     258        }
     259    }
     260
     261    return VINF_SUCCESS;
     262}
     263
     264
     265RTDECL(RTCPUID) RTMpCpuId(void)
     266{
     267    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     268
     269    if (g_pfnGetCurrentProcessorNumberEx)
     270    {
     271        PROCESSOR_NUMBER ProcNum;
     272        g_pfnGetCurrentProcessorNumberEx(&ProcNum);
     273        Assert(ProcNum.Group < g_cRtMpWinMaxCpuGroups);
     274        Assert(ProcNum.Number < g_aRtMpWinCpuGroups[ProcNum.Group].cMaxCpus);
     275        return g_aRtMpWinCpuGroups[ProcNum.Group].idFirstCpu + ProcNum.Number;
     276    }
     277
     278    if (g_pfnGetCurrentProcessorNumber)
     279    {
     280        /* Should be safe wrt processor numbering, I hope... Only affects W2k3 and Vista. */
     281        Assert(g_cRtMpWinMaxCpuGroups == 1);
     282        return g_pfnGetCurrentProcessorNumber();
     283    }
     284
     285    /* The API was introduced with W2K3 according to MSDN. */
     286#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
     287    return ASMGetApicId();
     288#else
     289# error "Not ported to this architecture."
     290    return NIL_RTAPICID;
     291#endif
     292}
     293
    47294
    48295RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
    49296{
    50     return idCpu < MAXIMUM_PROCESSORS ? idCpu : -1;
     297    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     298
     299    /* 1:1 mapping, just do range checking. */
     300    return idCpu < g_cRtMpWinMaxCpus ? idCpu : -1;
    51301}
    52302
     
    54304RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
    55305{
    56     return (unsigned)iCpu < MAXIMUM_PROCESSORS ? iCpu : NIL_RTCPUID;
     306    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     307
     308    /* 1:1 mapping, just do range checking. */
     309    return (unsigned)iCpu < g_cRtMpWinMaxCpus ? iCpu : NIL_RTCPUID;
    57310}
    58311
     
    60313RTDECL(RTCPUID) RTMpGetMaxCpuId(void)
    61314{
    62     return MAXIMUM_PROCESSORS - 1;
     315    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     316    return g_cRtMpWinMaxCpus - 1;
    63317}
    64318
     
    66320RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
    67321{
     322    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
    68323    RTCPUSET Set;
    69324    return RTCpuSetIsMember(RTMpGetOnlineSet(&Set), idCpu);
     
    73328RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
    74329{
    75     RTCPUSET Set;
    76     return RTCpuSetIsMember(RTMpGetSet(&Set), idCpu);
     330    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     331    /* Any CPU between 0 and g_cRtMpWinMaxCpus are possible. */
     332    return idCpu < g_cRtMpWinMaxCpus;
    77333}
    78334
     
    90346RTDECL(RTCPUID) RTMpGetCount(void)
    91347{
     348    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     349    return g_cRtMpWinMaxCpus;
     350}
     351
     352
     353RTDECL(RTCPUID) RTMpGetCoreCount(void)
     354{
     355    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     356    return g_cRtMpWinMaxCpuCores;
     357}
     358
     359
     360RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
     361{
     362    RTOnce(&g_MpInitOnce, rtMpWinInitOnce, NULL);
     363
     364    if (g_pfnGetLogicalProcessorInformationEx)
     365    {
     366        /*
     367         * Get the group relation info.
     368         *
     369         * In addition to the ASSUMPTIONS that are documented in rtMpWinInitOnce,
     370         * we ASSUME that PROCESSOR_GROUP_INFO::MaximumProcessorCount gives the
     371         * active processor mask width.
     372         */
     373        DWORD                                    cbInfo = g_cbRtMpWinGrpRelBuf;
     374        SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *pInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)alloca(cbInfo);
     375        AssertFatalMsg(g_pfnGetLogicalProcessorInformationEx(RelationGroup, pInfo, &cbInfo) != FALSE,
     376                       ("last error = %u, cbInfo = %u (in %u)\n", GetLastError(), cbInfo, g_cbRtMpWinGrpRelBuf));
     377        AssertFatalMsg(pInfo->Relationship == RelationGroup,
     378                       ("Relationship = %u, expected %u!\n", pInfo->Relationship, RelationGroup));
     379        AssertFatalMsg(pInfo->Group.MaximumGroupCount == g_cRtMpWinMaxCpuGroups,
     380                       ("MaximumGroupCount is %u, expected %u!\n", pInfo->Group.MaximumGroupCount, g_cRtMpWinMaxCpuGroups));
     381
     382        RTCpuSetEmpty(pSet);
     383        for (uint32_t idxGroup = 0; idxGroup < pInfo->Group.MaximumGroupCount; idxGroup++)
     384        {
     385            Assert(pInfo->Group.GroupInfo[idxGroup].MaximumProcessorCount == g_aRtMpWinCpuGroups[idxGroup].cMaxCpus);
     386            Assert(pInfo->Group.GroupInfo[idxGroup].ActiveProcessorCount  <= g_aRtMpWinCpuGroups[idxGroup].cMaxCpus);
     387
     388            KAFFINITY fActive = pInfo->Group.GroupInfo[idxGroup].ActiveProcessorMask;
     389            if (fActive != 0)
     390            {
     391#ifdef RT_STRICT
     392                uint32_t    cMembersLeft = pInfo->Group.GroupInfo[idxGroup].ActiveProcessorCount;
     393#endif
     394                int const   idxFirst  = g_aRtMpWinCpuGroups[idxGroup].idFirstCpu;
     395                int const   cMembers  = g_aRtMpWinCpuGroups[idxGroup].cMaxCpus;
     396                for (int idxMember = 0; idxMember < cMembers; idxMember++)
     397                {
     398                    if (fActive & 1)
     399                    {
     400#ifdef RT_STRICT
     401                        cMembersLeft--;
     402#endif
     403                        RTCpuSetAddByIndex(pSet, idxFirst + idxMember);
     404                        fActive >>= 1;
     405                        if (!fActive)
     406                            break;
     407                    }
     408                    else
     409                    {
     410                        fActive >>= 1;
     411                    }
     412                }
     413                Assert(cMembersLeft == 0);
     414            }
     415            else
     416                Assert(pInfo->Group.GroupInfo[idxGroup].ActiveProcessorCount == 0);
     417        }
     418
     419        return pSet;
     420    }
     421
     422    /*
     423     * Legacy fallback code.
     424     */
    92425    SYSTEM_INFO SysInfo;
    93426    GetSystemInfo(&SysInfo);
    94     Assert((RTCPUID)SysInfo.dwNumberOfProcessors == SysInfo.dwNumberOfProcessors);
    95     return SysInfo.dwNumberOfProcessors;
    96 }
    97 
    98 
    99 RTDECL(RTCPUID) RTMpGetCoreCount(void)
    100 {
    101     /*
    102      * Resolve the API dynamically (one try) as it requires XP w/ sp3 or later.
    103      */
    104     typedef BOOL (WINAPI *PFNGETLOGICALPROCINFO)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
    105     static PFNGETLOGICALPROCINFO s_pfnGetLogicalProcInfo = (PFNGETLOGICALPROCINFO)~(uintptr_t)0;
    106     if (s_pfnGetLogicalProcInfo == (PFNGETLOGICALPROCINFO)~(uintptr_t)0)
    107         s_pfnGetLogicalProcInfo = (PFNGETLOGICALPROCINFO)RTLdrGetSystemSymbol("kernel32.dll", "GetLogicalProcessorInformation");
    108 
    109     /*
    110      * Sadly, on XP and Server 2003, even if the API is present, it does not tell us
    111      * how many physical cores there are (any package will look like a single core).
    112      * That is worse than not using the API at all, so just skip it unless it's Vista+.
    113      */
    114     bool fIsVistaOrLater = false;
    115     OSVERSIONINFOEX OSInfoEx = { 0 };
    116     OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    117     if (   GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)
    118         && (OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT)
    119         && (OSInfoEx.dwMajorVersion >= 6))
    120         fIsVistaOrLater = true;
    121 
    122     if (s_pfnGetLogicalProcInfo && fIsVistaOrLater)
    123     {
    124         /*
    125          * Query the information. This unfortunately requires a buffer, so we
    126          * start with a guess and let windows advice us if it's too small.
    127          */
    128         DWORD                                   cbSysProcInfo = _4K;
    129         PSYSTEM_LOGICAL_PROCESSOR_INFORMATION   paSysInfo = NULL;
    130         BOOL                                    fRc = FALSE;
    131         do
    132         {
    133             cbSysProcInfo = RT_ALIGN_32(cbSysProcInfo, 256);
    134             void *pv = RTMemRealloc(paSysInfo, cbSysProcInfo);
    135             if (!pv)
    136                 break;
    137             paSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)pv;
    138             fRc = s_pfnGetLogicalProcInfo(paSysInfo, &cbSysProcInfo);
    139         } while (!fRc && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
    140         if (fRc)
    141         {
    142             /*
    143              * Parse the result.
    144              */
    145             uint32_t cCores = 0;
    146             uint32_t i      = cbSysProcInfo / sizeof(paSysInfo[0]);
    147             while (i-- > 0)
    148                 if (paSysInfo[i].Relationship == RelationProcessorCore)
    149                     cCores++;
    150 
    151             RTMemFree(paSysInfo);
    152             Assert(cCores > 0);
    153             return cCores;
    154         }
    155 
    156         RTMemFree(paSysInfo);
    157     }
    158 
    159     /* If we don't have the necessary API or if it failed, return the same
    160        value as the generic implementation. */
    161     return RTMpGetCount();
    162 }
    163 
    164 
    165 RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
    166 {
    167     SYSTEM_INFO SysInfo;
    168     GetSystemInfo(&SysInfo);
    169 /** @todo port to W2K8 / W7 w/ > 64 CPUs & grouping. */
    170427    return RTCpuSetFromU64(pSet, SysInfo.dwActiveProcessorMask);
    171428}
     
    182439RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void)
    183440{
    184     /** @todo this isn't entirely correct. */
     441    /** @todo this isn't entirely correct, but whatever. */
    185442    return RTMpGetCoreCount();
    186443}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette