Changeset 48812 in vbox for trunk/src/VBox/Runtime/r3/solaris
- Timestamp:
- Oct 2, 2013 9:30:32 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 89455
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/solaris/mp-solaris.cpp
r48768 r48812 58 58 /** The number of entries in g_papCpuInfo */ 59 59 static RTCPUID g_capCpuInfo; 60 /** Array of core ids. */ 61 static uint64_t *g_pu64CoreIds; 62 /** Number of entries in g_pu64CoreIds. */ 63 static size_t g_cu64CoreIds; 64 /** Number of cores in the system. */ 65 static 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 */ 74 static 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 */ 89 static 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 } 60 119 61 120 … … 81 140 if (g_papCpuInfo) 82 141 { 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) 85 145 { 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)) 88 148 { 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) 90 151 { 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 } 94 158 } 159 160 rc = rtMpSolarisGetCoreIds(); 161 if (RT_SUCCESS(rc)) 162 return VINF_SUCCESS; 163 else 164 Log(("rtMpSolarisGetCoreIds failed. rc=%Rrc\n", rc)); 95 165 } 96 166 97 return VINF_SUCCESS; 167 RTMemFree(g_pu64CoreIds); 168 g_pu64CoreIds = NULL; 98 169 } 170 else 171 rc = VERR_NO_MEMORY; 99 172 100 173 /* bail out, we failed. */ 101 174 RTMemFree(g_papCpuInfo); 175 g_papCpuInfo = NULL; 102 176 } 103 177 else … … 119 193 120 194 /** 195 * RTOnceEx() cleanup function. 196 * 197 * @param pvUser Unused. 198 * @param fLazyCleanUpOk Whether lazy cleanup is okay or not. 199 */ 200 static 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 /** 121 210 * Worker for RTMpGetCurFrequency and RTMpGetMaxFrequency. 122 211 * … … 129 218 { 130 219 uint64_t u64 = 0; 131 int rc = RTOnce (&g_MpSolarisOnce, rtMpSolarisOnce, NULL);220 int rc = RTOnceEx(&g_MpSolarisOnce, rtMpSolarisOnce, rtMpSolarisCleanUp, NULL /* pvUser */); 132 221 if (RT_SUCCESS(rc)) 133 222 { … … 281 370 { 282 371 #ifdef RT_STRICT 283 longcCpusPresent = 0;372 RTCPUID cCpusPresent = 0; 284 373 #endif 285 374 RTCpuSetEmpty(pSet); … … 312 401 } 313 402 403 404 RTDECL(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 414 RTDECL(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.