VirtualBox

Ignore:
Timestamp:
Oct 2, 2013 9:30:32 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
89455
Message:

Runtime/Solaris: RTMpGetCoreCount, RTMpGetOnlineCoreCount implementations.

File:
1 edited

Legend:

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

    r48768 r48812  
    5858/** The number of entries in g_papCpuInfo */
    5959static RTCPUID      g_capCpuInfo;
     60/** Array of core ids.  */
     61static uint64_t    *g_pu64CoreIds;
     62/** Number of entries in g_pu64CoreIds. */
     63static size_t       g_cu64CoreIds;
     64/** Number of cores in the system. */
     65static size_t       g_cCores;
     66
     67
     68/**
     69 * Helper for getting the core ID for a given CPU/strand/hyperthread.
     70 *
     71 * @returns The core ID.
     72 * @param   idCpu       The CPU ID instance.
     73 */
     74static inline uint64_t rtMpSolarisGetCoreId(RTCPUID idCpu)
     75{
     76    kstat_named_t *pStat = (kstat_named_t *)kstat_data_lookup(g_papCpuInfo[idCpu], (char *)"core_id");
     77    Assert(pStat->data_type == KSTAT_DATA_LONG);
     78    Assert(pStat->value.l >= 0);
     79    AssertCompile(sizeof(uint64_t) >= sizeof(long));    /* Paranoia. */
     80    return (uint64_t)pStat->value.l;
     81}
     82
     83
     84/**
     85 * Populates 'g_pu64CoreIds' array with unique core identifiers in the system.
     86 *
     87 * @returns VBox status code.
     88 */
     89static int rtMpSolarisGetCoreIds(void)
     90{
     91    for (RTCPUID idCpu = 0; idCpu < g_capCpuInfo; idCpu++)
     92    {
     93        if (kstat_read(g_pKsCtl, g_papCpuInfo[idCpu], 0) != -1)
     94        {
     95            /* Strands/Hyperthreads share the same core ID. */
     96            uint64_t u64CoreId  = rtMpSolarisGetCoreId(idCpu);
     97            bool     fAddedCore = false;
     98            for (RTCPUID i = 0; i < g_cCores; i++)
     99            {
     100                if (g_pu64CoreIds[i] == u64CoreId)
     101                {
     102                    fAddedCore = true;
     103                    break;
     104                }
     105            }
     106
     107            if (!fAddedCore)
     108            {
     109                g_pu64CoreIds[g_cCores] = u64CoreId;
     110                ++g_cCores;
     111            }
     112        }
     113        else
     114            return VERR_INTERNAL_ERROR_2;
     115    }
     116
     117    return VINF_SUCCESS;
     118}
    60119
    61120
     
    81140        if (g_papCpuInfo)
    82141        {
    83             rc = RTCritSectInit(&g_MpSolarisCritSect);
    84             if (RT_SUCCESS(rc))
     142            g_cu64CoreIds = g_capCpuInfo;
     143            g_pu64CoreIds = (uint64_t *)RTMemAllocZ(g_cu64CoreIds * sizeof(uint64_t));
     144            if (g_pu64CoreIds)
    85145            {
    86                 RTCPUID i = 0;
    87                 for (kstat_t *pKsp = g_pKsCtl->kc_chain; pKsp != NULL; pKsp = pKsp->ks_next)
     146                rc = RTCritSectInit(&g_MpSolarisCritSect);
     147                if (RT_SUCCESS(rc))
    88148                {
    89                     if (!strcmp(pKsp->ks_module, "cpu_info"))
     149                    RTCPUID i = 0;
     150                    for (kstat_t *pKsp = g_pKsCtl->kc_chain; pKsp != NULL; pKsp = pKsp->ks_next)
    90151                    {
    91                         AssertBreak(i < g_capCpuInfo);
    92                         g_papCpuInfo[i++] = pKsp;
    93                         /** @todo ks_instance == cpu_id (/usr/src/uts/common/os/cpu.c)? Check this and fix it ASAP. */
     152                        if (!RTStrCmp(pKsp->ks_module, "cpu_info"))
     153                        {
     154                            AssertBreak(i < g_capCpuInfo);
     155                            g_papCpuInfo[i++] = pKsp;
     156                            /** @todo ks_instance == cpu_id (/usr/src/uts/common/os/cpu.c)? Check this and fix it ASAP. */
     157                        }
    94158                    }
     159
     160                    rc = rtMpSolarisGetCoreIds();
     161                    if (RT_SUCCESS(rc))
     162                        return VINF_SUCCESS;
     163                    else
     164                        Log(("rtMpSolarisGetCoreIds failed. rc=%Rrc\n", rc));
    95165                }
    96166
    97                 return VINF_SUCCESS;
     167                RTMemFree(g_pu64CoreIds);
     168                g_pu64CoreIds = NULL;
    98169            }
     170            else
     171                rc = VERR_NO_MEMORY;
    99172
    100173            /* bail out, we failed. */
    101174            RTMemFree(g_papCpuInfo);
     175            g_papCpuInfo = NULL;
    102176        }
    103177        else
     
    119193
    120194/**
     195 * RTOnceEx() cleanup function.
     196 *
     197 * @param   pvUser              Unused.
     198 * @param   fLazyCleanUpOk      Whether lazy cleanup is okay or not.
     199 */
     200static DECLCALLBACK(void) rtMpSolarisCleanUp(void *pvUser, bool fLazyCleanUpOk)
     201{
     202    if (g_pKsCtl)
     203        kstat_close(g_pKsCtl);
     204    RTMemFree(g_pu64CoreIds);
     205    RTMemFree(g_papCpuInfo);
     206}
     207
     208
     209/**
    121210 * Worker for RTMpGetCurFrequency and RTMpGetMaxFrequency.
    122211 *
     
    129218{
    130219    uint64_t u64 = 0;
    131     int rc = RTOnce(&g_MpSolarisOnce, rtMpSolarisOnce, NULL);
     220    int rc = RTOnceEx(&g_MpSolarisOnce, rtMpSolarisOnce, rtMpSolarisCleanUp, NULL /* pvUser */);
    132221    if (RT_SUCCESS(rc))
    133222    {
     
    281370{
    282371#ifdef RT_STRICT
    283     long cCpusPresent = 0;
     372    RTCPUID cCpusPresent = 0;
    284373#endif
    285374    RTCpuSetEmpty(pSet);
     
    312401}
    313402
     403
     404RTDECL(RTCPUID) RTMpGetCoreCount(void)
     405{
     406    int rc = RTOnceEx(&g_MpSolarisOnce, rtMpSolarisOnce, rtMpSolarisCleanUp, NULL /* pvUser */);
     407    if (RT_SUCCESS(rc))
     408        return g_cCores;
     409
     410    return 0;
     411}
     412
     413
     414RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void)
     415{
     416    RTCPUID uOnlineCores = 0;
     417    int rc = RTOnceEx(&g_MpSolarisOnce, rtMpSolarisOnce, rtMpSolarisCleanUp, NULL /* pvUser */);
     418    if (RT_SUCCESS(rc))
     419    {
     420        rc = RTCritSectEnter(&g_MpSolarisCritSect);
     421        AssertRC(rc);
     422
     423        /*
     424         * For each core in the system, count how many are currently online.
     425         */
     426        for (RTCPUID j = 0; j < g_cCores; j++)
     427        {
     428            uint64_t u64CoreId = g_pu64CoreIds[j];
     429            for (RTCPUID idCpu = 0; idCpu < g_capCpuInfo; idCpu++)
     430            {
     431                rc = kstat_read(g_pKsCtl, g_papCpuInfo[idCpu], 0);
     432                AssertReturn(rc != -1, 0 /* rc */);
     433                uint64_t u64ThreadCoreId = rtMpSolarisGetCoreId(idCpu);
     434                if (u64ThreadCoreId == u64CoreId)
     435                {
     436                    kstat_named_t *pStat = (kstat_named_t *)kstat_data_lookup(g_papCpuInfo[idCpu], (char *)"state");
     437                    Assert(pStat->data_type == KSTAT_DATA_CHAR);
     438                    if(   !RTStrNCmp(pStat->value.c, PS_ONLINE, sizeof(PS_ONLINE))
     439                       || !RTStrNCmp(pStat->value.c, PS_NOINTR, sizeof(PS_NOINTR)))
     440                    {
     441                        uOnlineCores++;
     442                        break;      /* Move to the next core. We have at least 1 hyperthread online in the current core. */
     443                    }
     444                }
     445            }
     446        }
     447
     448        RTCritSectLeave(&g_MpSolarisCritSect);
     449    }
     450
     451    return uOnlineCores;
     452}
     453
Note: See TracChangeset for help on using the changeset viewer.

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