int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { unsigned int numcpus; uv_cpu_info_t* ci; int err; FILE* statfile_fp; *cpu_infos = NULL; *count = 0; statfile_fp = uv__open_file("/proc/stat"); if (statfile_fp == NULL) return UV__ERR(errno); err = uv__cpu_num(statfile_fp, &numcpus); if (err < 0) goto out; err = UV_ENOMEM; ci = uv__calloc(numcpus, sizeof(*ci)); if (ci == NULL) goto out; err = read_models(numcpus, ci); if (err == 0) err = read_times(statfile_fp, numcpus, ci); if (err) { uv_free_cpu_info(ci, numcpus); goto out; } /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo. * We don't check for errors here. Worst case, the field is left zero. */ if (ci[0].speed == 0) read_speeds(numcpus, ci); *cpu_infos = ci; *count = numcpus; err = 0; out: if (fclose(statfile_fp)) if (errno != EINTR && errno != EINPROGRESS) abort(); return err; }
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { unsigned int numcpus; uv_cpu_info_t* ci; int err; *cpu_infos = NULL; *count = 0; numcpus = sysconf(_SC_NPROCESSORS_ONLN); assert(numcpus != (unsigned int) -1); assert(numcpus != 0); ci = uv__calloc(numcpus, sizeof(*ci)); if (ci == NULL) return -ENOMEM; err = read_models(numcpus, ci); if (err == 0) err = read_times(numcpus, ci); if (err) { uv_free_cpu_info(ci, numcpus); return err; } /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo. * We don't check for errors here. Worst case, the field is left zero. */ if (ci[0].speed == 0) read_speeds(numcpus, ci); *cpu_infos = ci; *count = numcpus; return 0; }
int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { uv_cpu_info_t* cpu_infos; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; DWORD sppi_size; SYSTEM_INFO system_info; DWORD cpu_count, r, i; NTSTATUS status; ULONG result_size; int err; uv_cpu_info_t* cpu_info; cpu_infos = NULL; cpu_count = 0; sppi = NULL; uv__once_init(); GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos); if (cpu_infos == NULL) { err = ERROR_OUTOFMEMORY; goto error; } sppi_size = cpu_count * sizeof(*sppi); sppi = uv__malloc(sppi_size); if (sppi == NULL) { err = ERROR_OUTOFMEMORY; goto error; } status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sppi_size, &result_size); if (!NT_SUCCESS(status)) { err = pRtlNtStatusToDosError(status); goto error; } assert(result_size == sppi_size); for (i = 0; i < cpu_count; i++) { WCHAR key_name[128]; HKEY processor_key; DWORD cpu_speed; DWORD cpu_speed_size = sizeof(cpu_speed); WCHAR cpu_brand[256]; DWORD cpu_brand_size = sizeof(cpu_brand); size_t len; len = _snwprintf(key_name, ARRAY_SIZE(key_name), L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i); assert(len > 0 && len < ARRAY_SIZE(key_name)); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &processor_key); if (r != ERROR_SUCCESS) { err = GetLastError(); goto error; } if (RegQueryValueExW(processor_key, L"~MHz", NULL, NULL, (BYTE*) &cpu_speed, &cpu_speed_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } if (RegQueryValueExW(processor_key, L"ProcessorNameString", NULL, NULL, (BYTE*) &cpu_brand, &cpu_brand_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } RegCloseKey(processor_key); cpu_info = &cpu_infos[i]; cpu_info->speed = cpu_speed; cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart) / 10000; cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; cpu_info->cpu_times.nice = 0; uv__convert_utf16_to_utf8(cpu_brand, cpu_brand_size / sizeof(WCHAR), &(cpu_info->model)); } uv__free(sppi); *cpu_count_ptr = cpu_count; *cpu_infos_ptr = cpu_infos; return 0; error: /* This is safe because the cpu_infos array is zeroed on allocation. */ for (i = 0; i < cpu_count; i++) uv__free(cpu_infos[i].model); uv__free(cpu_infos); uv__free(sppi); return uv_translate_sys_error(err); }