diff --git a/hadoop-common-project/hadoop-common/src/main/winutils/systeminfo.c b/hadoop-common-project/hadoop-common/src/main/winutils/systeminfo.c index b7093a7b7d3..12afcda9e00 100644 --- a/hadoop-common-project/hadoop-common/src/main/winutils/systeminfo.c +++ b/hadoop-common-project/hadoop-common/src/main/winutils/systeminfo.c @@ -43,6 +43,33 @@ typedef struct _PROCESSOR_POWER_INFORMATION { ULONG CurrentIdleState; } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION; +//---------------------------------------------------------------------------- +// Function: SwitchToCpuGroup +// +// Description: +// Switch current thread to be running on specified CPU group +// +// Returns: +// EXIT_SUCCESS: On success +// EXIT_FAILURE: otherwise +int SwitchToCpuGroup(WORD cpuGroupIndex) +{ + GROUP_AFFINITY affinity; + GROUP_AFFINITY previousAffinity; + + if(!GetNumaNodeProcessorMaskEx(cpuGroupIndex, &affinity)) + { + ReportErrorCode(L"GetNumaNodeProcessorMaskEx", GetLastError()); + return EXIT_FAILURE; + } + if(!SetThreadGroupAffinity(GetCurrentThread(), &affinity, &previousAffinity)) + { + ReportErrorCode(L"SetThreadGroupAffinity", GetLastError()); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + //---------------------------------------------------------------------------- // Function: SystemInfo // @@ -59,13 +86,19 @@ int SystemInfo() SYSTEM_INFO sysInfo; FILETIME idleTimeFt, kernelTimeFt, userTimeFt; ULARGE_INTEGER idleTime, kernelTime, userTime; - ULONGLONG cpuTimeMs; + ULONGLONG groupCpuTimeMs; + ULONGLONG cpuTimeMs = 0; size_t size; LPBYTE pBuffer; PROCESSOR_POWER_INFORMATION const *ppi; - ULONGLONG cpuFrequencyKhz; + ULONGLONG cpuFrequencyKhz = 0; NTSTATUS status; LONGLONG diskRead, diskWrite, netRead, netWrite; + WORD cpuGroupCount; + WORD cpuGroupIndex; + ULONG_PTR cpuMask; + DWORD cpuCount = 0; + DWORD cpuIndex = 0; ZeroMemory(&memInfo, sizeof(PERFORMANCE_INFORMATION)); memInfo.cb = sizeof(PERFORMANCE_INFORMATION); @@ -79,40 +112,63 @@ int SystemInfo() memSize = memInfo.PhysicalTotal*memInfo.PageSize; memFree = memInfo.PhysicalAvailable*memInfo.PageSize; - GetSystemInfo(&sysInfo); - - if(!GetSystemTimes(&idleTimeFt, &kernelTimeFt, &userTimeFt)) + cpuGroupCount = GetActiveProcessorGroupCount(); + if(cpuGroupCount == 0) { - ReportErrorCode(L"GetSystemTimes", GetLastError()); + ReportErrorCode(L"GetActiveProcessorGroupCount", GetLastError()); return EXIT_FAILURE; } - idleTime.HighPart = idleTimeFt.dwHighDateTime; - idleTime.LowPart = idleTimeFt.dwLowDateTime; - kernelTime.HighPart = kernelTimeFt.dwHighDateTime; - kernelTime.LowPart = kernelTimeFt.dwLowDateTime; - userTime.HighPart = userTimeFt.dwHighDateTime; - userTime.LowPart = userTimeFt.dwLowDateTime; - - cpuTimeMs = (kernelTime.QuadPart - idleTime.QuadPart + userTime.QuadPart)/10000; - - // allocate buffer to get info for each processor - size = sysInfo.dwNumberOfProcessors * sizeof(PROCESSOR_POWER_INFORMATION); - pBuffer = (BYTE*) LocalAlloc(LPTR, size); - if(!pBuffer) + for(cpuGroupIndex = 0; cpuGroupIndex < cpuGroupCount; cpuGroupIndex++) { - ReportErrorCode(L"LocalAlloc", GetLastError()); - return EXIT_FAILURE; - } - status = CallNtPowerInformation(ProcessorInformation, NULL, 0, pBuffer, (long)size); - if(0 != status) - { - fwprintf_s(stderr, L"Error in CallNtPowerInformation. Err:%d\n", status); + if(SwitchToCpuGroup(cpuGroupIndex) != EXIT_SUCCESS) + { + return EXIT_FAILURE; + } + + if(!GetSystemTimes(&idleTimeFt, &kernelTimeFt, &userTimeFt)) + { + ReportErrorCode(L"GetSystemTimes", GetLastError()); + return EXIT_FAILURE; + } + idleTime.HighPart = idleTimeFt.dwHighDateTime; + idleTime.LowPart = idleTimeFt.dwLowDateTime; + kernelTime.HighPart = kernelTimeFt.dwHighDateTime; + kernelTime.LowPart = kernelTimeFt.dwLowDateTime; + userTime.HighPart = userTimeFt.dwHighDateTime; + userTime.LowPart = userTimeFt.dwLowDateTime; + + groupCpuTimeMs = (kernelTime.QuadPart - idleTime.QuadPart + userTime.QuadPart)/10000; + cpuTimeMs += groupCpuTimeMs; + + GetSystemInfo(&sysInfo); + cpuCount += sysInfo.dwNumberOfProcessors; + + LogDebugMessage(L"CPU group %u: cores=%u, groupCpuTimeMs=%I64u\n", + cpuGroupIndex, groupCpuTimeMs, sysInfo.dwNumberOfProcessors); + + // allocate buffer to get info for each processor + size = sysInfo.dwNumberOfProcessors * sizeof(PROCESSOR_POWER_INFORMATION); + pBuffer = (BYTE*) LocalAlloc(LPTR, size); + if(!pBuffer) + { + ReportErrorCode(L"LocalAlloc", GetLastError()); + return EXIT_FAILURE; + } + status = CallNtPowerInformation(ProcessorInformation, NULL, 0, pBuffer, (long)size); + if(0 != status) + { + fwprintf_s(stderr, L"Error in CallNtPowerInformation. Err:%d\n", status); + LocalFree(pBuffer); + return EXIT_FAILURE; + } + ppi = (PROCESSOR_POWER_INFORMATION const *)pBuffer; + for(cpuIndex = 0; cpuIndex < sysInfo.dwNumberOfProcessors;cpuIndex++) + { + cpuFrequencyKhz += ppi[cpuIndex].MaxMhz*1000; + } LocalFree(pBuffer); - return EXIT_FAILURE; } - ppi = (PROCESSOR_POWER_INFORMATION const *)pBuffer; - cpuFrequencyKhz = ppi->MaxMhz*1000; - LocalFree(pBuffer); + cpuFrequencyKhz /= cpuCount; status = GetDiskAndNetwork(&diskRead, &diskWrite, &netRead, &netWrite); if(0 != status) @@ -122,7 +178,7 @@ int SystemInfo() } fwprintf_s(stdout, L"%Iu,%Iu,%Iu,%Iu,%u,%I64u,%I64u,%I64d,%I64d,%I64d,%I64d\n", vmemSize, memSize, - vmemFree, memFree, sysInfo.dwNumberOfProcessors, cpuFrequencyKhz, cpuTimeMs, + vmemFree, memFree, cpuCount, cpuFrequencyKhz, cpuTimeMs, diskRead, diskWrite, netRead, netWrite); return EXIT_SUCCESS;