Changeset 11241 in vbox for trunk/src/VBox
- Timestamp:
- Aug 8, 2008 12:51:27 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 34318
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/solaris/mp-solaris.cpp
r11205 r11241 29 29 */ 30 30 31 32 31 /******************************************************************************* 33 32 * Header Files * … … 45 44 #include <iprt/alloc.h> 46 45 #include <iprt/log.h> 46 #include <iprt/once.h> 47 #include <iprt/critsect.h> 47 48 48 static kstat_ctl_t *g_kc;49 static kstat_t **g_cpuInfo;50 static RTCPUID g_nCPUs;51 49 52 void rtLookupCpuInfoStats() 50 /******************************************************************************* 51 * Global Variables * 52 *******************************************************************************/ 53 /** Initialization serializing (rtMpSolarisOnce). */ 54 static RTONCE g_MpSolarisOnce = RTONCE_INITIALIZER; 55 /** Critical section serializing access to kstat. */ 56 static RTCRITSECT g_MpSolarisCritSect; 57 /** The kstat handle. */ 58 static kstat_ctl_t *g_pKsCtl; 59 /** Array pointing to the cpu_info instances. */ 60 static kstat_t **g_papCpuInfo; 61 /** The number of entries in g_papCpuInfo */ 62 static RTCPUID g_capCpuInfo; 63 64 65 /** 66 * Run once function that initializes the kstats we need here. 67 * 68 * @returns IPRT status code. 69 * @param pvUser1 Unused. 70 * @param pvUser2 Unused. 71 */ 72 static DECLCALLBACK(int) rtMpSolarisOnce(void *pvUser1, void *pvUser2) 53 73 { 54 g_kc = kstat_open(); 55 if (!g_kc) 74 int rc = VINF_SUCCESS; 75 NOREF(pvUser1); NOREF(pvUser2); 76 77 /* 78 * Open kstat and find the cpu_info entries for each of the CPUs. 79 */ 80 g_pKsCtl = kstat_open(); 81 if (g_pKsCtl) 56 82 { 57 Log(("kstat_open() -> %d\n", errno)); 58 return; 83 g_capCpuInfo = RTMpGetCount(); 84 g_papCpuInfo = (kstat_t **)RTMemAlloc(g_capCpuInfo * sizeof(kstat_t *)); 85 if (g_papCpuInfo) 86 { 87 rc = RTCritSectInit(&g_MpSolarisCritSect); 88 if (RT_SUCCESS(rc)) 89 { 90 RTCPUID i = 0; 91 for (kstat_t *pKsp = g_pKsCtl->kc_chain; pKsp != NULL; pKsp = pKsp->ks_next) 92 { 93 if (!strcmp(pKsp->ks_module, "cpu_info")) 94 { 95 AssertBreak(i < g_capCpuInfo); 96 g_papCpuInfo[i++] = pKsp; 97 /** @todo ks_instance == cpu_id (/usr/src/uts/common/os/cpu.c)? Check this and fix it ASAP. */ 98 } 99 } 100 101 return VINF_SUCCESS; 102 } 103 104 /* bail out, we failed. */ 105 RTMemFree(g_papCpuInfo); 106 } 107 else 108 rc = VERR_NO_MEMORY; 109 kstat_close(g_pKsCtl); 110 g_pKsCtl = NULL; 111 } 112 else 113 { 114 rc = RTErrConvertFromErrno(errno); 115 if (RT_SUCCESS(rc)) 116 rc = VERR_INTERNAL_ERROR; 117 Log(("kstat_open() -> %d (%Rrc)\n", errno, rc)); 59 118 } 60 119 61 g_nCPUs = RTMpGetCount(); 62 g_cpuInfo = (kstat_t**)RTMemAlloc(g_nCPUs * sizeof(kstat_t*)); 63 if (!g_cpuInfo) 120 return rc; 121 } 122 123 124 /** 125 * Worker for RTMpGetCurFrequency and RTMpGetMaxFrequency. 126 * 127 * @returns The desired frequency on success, 0 on failure. 128 * 129 * @param idCpu The CPU ID. 130 * @param pszStatName The cpu_info stat name. 131 */ 132 static uint64_t rtMpSolarisGetFrequency(RTCPUID idCpu, char *pszStatName) 133 { 134 uint64_t u64 = 0; 135 int rc = RTOnce(&g_MpSolarisOnce, rtMpSolarisOnce, NULL, NULL); 136 if (RT_SUCCESS(rc)) 64 137 { 65 Log(("RTMemAlloc() -> NULL\n")); 66 return; 138 if ( idCpu < g_capCpuInfo 139 && g_papCpuInfo[idCpu]) 140 { 141 rc = RTCritSectEnter(&g_MpSolarisCritSect); 142 AssertRC(rc); 143 if (RT_SUCCESS(rc)) 144 { 145 if (kstat_read(g_pKsCtl, g_papCpuInfo[idCpu], 0) != -1) 146 { 147 kstat_named_t *pStat = (kstat_named_t *)kstat_data_lookup(g_papCpuInfo[idCpu], pszStatName); 148 if (pStat) 149 { 150 Assert(pStat->data_type == KSTAT_DATA_UINT64 || pStat->data_type == KSTAT_DATA_LONG); 151 switch (pStat->data_type) 152 { 153 case KSTAT_DATA_UINT64: u64 = pStat->value.ui64; break; /* current_clock_Hz */ 154 case KSTAT_DATA_INT32: u64 = pStat->value.i32; break; /* clock_MHz */ 155 156 /* just in case... */ 157 case KSTAT_DATA_UINT32: u64 = pStat->value.ui32; break; 158 case KSTAT_DATA_INT64: u64 = pStat->value.i64; break; 159 default: 160 AssertMsgFailed(("%d\n", pStat->data_type)); 161 break; 162 } 163 } 164 else 165 Log(("kstat_data_lookup(%s) -> %d\n", pszStatName, errno)); 166 } 167 else 168 Log(("kstat_read() -> %d\n", errno)); 169 RTCritSectLeave(&g_MpSolarisCritSect); 170 } 171 } 172 else 173 Log(("invalid idCpu: %d (g_capCpuInfo=%d)\n", (int)idCpu, (int)g_capCpuInfo)); 67 174 } 68 175 69 RTCPUID i = 0; 70 kstat_t *ksp; 71 for (ksp = g_kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) 72 { 73 if (strcmp(ksp->ks_module, "cpu_info") == 0) 74 { 75 g_cpuInfo[i++] = ksp; 76 } 77 Assert(i <= g_nCPUs); 78 } 79 } 80 81 static uint64_t rtMpGetFrequency(RTCPUID idCpu, char *statName) 82 { 83 if (!g_kc) 84 rtLookupCpuInfoStats(); 85 86 if (idCpu < g_nCPUs && g_cpuInfo[idCpu]) 87 if (kstat_read(g_kc, g_cpuInfo[idCpu], 0) != -1) 88 { 89 kstat_named_t *kn; 90 kn = (kstat_named_t *)kstat_data_lookup(g_cpuInfo[idCpu], statName); 91 if (kn) 92 return kn->value.ul; 93 else 94 Log(("kstat_data_lookup(%s) -> %d\n", statName, errno)); 95 } 96 else 97 Log(("kstat_read() -> %d\n", errno)); 98 else 99 Log(("invalid idCpu: %d\n", idCpu)); 100 101 return 0; 176 return u64; 102 177 } 103 178 … … 105 180 RTDECL(uint32_t) RTMpGetCurFrequency(RTCPUID idCpu) 106 181 { 107 return rtMp GetFrequency(idCpu, "current_clock_Hz") / 1000000;182 return rtMpSolarisGetFrequency(idCpu, "current_clock_Hz") / 1000000; 108 183 } 184 109 185 110 186 RTDECL(uint32_t) RTMpGetMaxFrequency(RTCPUID idCpu) 111 187 { 112 return rtMp GetFrequency(idCpu, "clock_MHz");188 return rtMpSolarisGetFrequency(idCpu, "clock_MHz"); 113 189 } 190
Note:
See TracChangeset
for help on using the changeset viewer.