Changeset 46635 in vbox
- Timestamp:
- Jun 18, 2013 5:03:32 PM (11 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Runtime/r3/win/mp-win.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/mp-win.cpp
r46625 r46635 31 31 #define LOG_GROUP RTLOGGROUP_SYSTEM 32 32 #include <Windows.h> 33 33 34 #include <iprt/mp.h> 35 #include "internal/iprt.h" 36 37 #include <iprt/assert.h> 34 38 #include <iprt/cpuset.h> 35 #include <iprt/ assert.h>39 #include <iprt/ldr.h> 36 40 #include <iprt/mem.h> 37 41 … … 92 96 } 93 97 98 94 99 RTDECL(RTCPUID) RTMpGetCoreCount(void) 95 100 { 96 BOOL (WINAPI *pfnGetLogicalProcInfo)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); 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"); 97 108 98 pfnGetLogicalProcInfo = (BOOL (WINAPI *)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD)) 99 GetProcAddress(GetModuleHandle("kernel32.dll"), "GetLogicalProcessorInformation"); 100 /* 0 represents an error condition. We cannot return VERR* error codes as caller expects a 101 * unsigned value of core count.*/ 102 if (!pfnGetLogicalProcInfo) 103 return 0; 109 if (s_pfnGetLogicalProcInfo) 110 { 111 /* 112 * Query the information. This unfortunately requires a buffer, so we 113 * start with a guess and let windows advice us if it's too small. 114 */ 115 DWORD cbSysProcInfo = _4K / 16; 116 PSYSTEM_LOGICAL_PROCESSOR_INFORMATION paSysInfo = NULL; 117 BOOL fRc = FALSE; 118 do 119 { 120 cbSysProcInfo = RT_ALIGN_32(cbSysProcInfo, 256); 121 void *pv = RTMemRealloc(paSysInfo, cbSysProcInfo); 122 if (!pv) 123 break; 124 paSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)pv; 125 fRc = s_pfnGetLogicalProcInfo(paSysInfo, &cbSysProcInfo); 126 } while (!fRc && GetLastError() == ERROR_INSUFFICIENT_BUFFER); 127 if (fRc) 128 { 129 /* 130 * Parse the result. 131 */ 132 uint32_t cCores = 0; 133 uint32_t i = cbSysProcInfo / sizeof(paSysInfo[0]); 134 while (i-- > 0) 135 if (paSysInfo[i].Relationship == RelationProcessorCore) 136 cCores++; 104 137 105 PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pSysInfo = NULL; 106 DWORD cbSysProcInfo = 0; 107 BOOL fRc = pfnGetLogicalProcInfo(pSysInfo, &cbSysProcInfo); 108 if (!fRc) 109 { 110 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 111 pSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)RTMemAlloc(cbSysProcInfo); 138 RTMemFree(paSysInfo); 139 Assert(cCores > 0); 140 return cCores; 141 } 142 143 RTMemFree(paSysInfo); 112 144 } 113 145 114 RTCPUID cCores = 0; 115 if (pSysInfo) 116 { 117 fRc = pfnGetLogicalProcInfo(pSysInfo, &cbSysProcInfo); 118 if (fRc) 119 { 120 PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pSysInfoTmp = pSysInfo; 121 size_t offs = 0; 122 while (offs + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= cbSysProcInfo) 123 { 124 switch (pSysInfoTmp->Relationship) 125 { 126 case RelationProcessorCore: 127 cCores++; 128 break; 129 case RelationCache: 130 case RelationNumaNode: 131 case RelationProcessorPackage: 132 default: 133 ; 134 } 135 offs += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); 136 pSysInfoTmp++; 137 } 138 } 139 RTMemFree(pSysInfo); 140 } 141 return cCores; 146 /* If we don't have the necessary API or if it failed, return the same 147 value as the generic implementation. */ 148 return RTMpGetCount(); 142 149 } 150 143 151 144 152 RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
Note:
See TracChangeset
for help on using the changeset viewer.

