Skip to content

Commit

Permalink
sysinfo.cc: Always abort on GetNumCPUs failure
Browse files Browse the repository at this point in the history
Defines a wrapper function, CheckNumCPUs, which enforces that GetNumCPUs
never returns fewer than one CPU.  There is no reasonable way to
continue if we are unable to identify the number of CPUs.

This is a followup to #1753.

Signed-off-by: Sam James <[email protected]>
  • Loading branch information
thesamesam committed Feb 14, 2024
1 parent 385033b commit ee974be
Showing 1 changed file with 23 additions and 18 deletions.
41 changes: 23 additions & 18 deletions src/sysinfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -474,44 +474,51 @@ std::string GetSystemName() {
#endif // Catch-all POSIX block.
}

int CheckNumCPUs(const int num_cpus) {
if (num_cpus < 1) {
PrintErrorAndDie(
"Unable to extract number of CPUs. If your platform uses "
"/proc/cpuinfo, custom support may need to be added.");
}
return num_cpus;
}

int GetNumCPUs() {
#ifdef BENCHMARK_HAS_SYSCTL
int num_cpu = -1;
if (GetSysctl("hw.ncpu", &num_cpu)) return num_cpu;
fprintf(stderr, "Err: %s\n", strerror(errno));
std::exit(EXIT_FAILURE);
if (GetSysctl("hw.ncpu", &num_cpu)) return CheckNumCPUs(num_cpu);
PrintErrorAndDie("Err: ", sterror(errno));
#elif defined(BENCHMARK_OS_WINDOWS)
SYSTEM_INFO sysinfo;
// Use memset as opposed to = {} to avoid GCC missing initializer false
// positives.
std::memset(&sysinfo, 0, sizeof(SYSTEM_INFO));
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors; // number of logical
// processors in the current
// group
return CheckNumCPUs(sysinfo.dwNumberOfProcessors); // number of logical
// processors in the
// current group
#elif defined(BENCHMARK_OS_SOLARIS)
// Returns -1 in case of a failure.
long num_cpu = sysconf(_SC_NPROCESSORS_ONLN);
if (num_cpu < 0) {
fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed with error: %s\n",
strerror(errno));
PrintErrorAndDie("sysconf(_SC_NPROCESSORS_ONLN) failed with error: ",
strerror(errno));
}
return (int)num_cpu;
return CheckNumCPUs(static_cast<int>(num_cpu));
#elif defined(BENCHMARK_OS_QNX)
return static_cast<int>(_syspage_ptr->num_cpu);
return CheckNumCPUs(static_cast<int>(_syspage_ptr->num_cpu));
#elif defined(BENCHMARK_OS_QURT)
qurt_sysenv_max_hthreads_t hardware_threads;
if (qurt_sysenv_get_max_hw_threads(&hardware_threads) != QURT_EOK) {
hardware_threads.max_hthreads = 1;
}
return hardware_threads.max_hthreads;
return CheckNumCPUs(hardware_threads.max_hthreads);
#else
int num_cpus = 0;
int max_id = -1;
std::ifstream f("/proc/cpuinfo");
if (!f.is_open()) {
std::cerr << "failed to open /proc/cpuinfo\n";
return -1;
PrintErrorAndDie("Failed to open /proc/cpuinfo");
}
#if defined(__alpha__)
const std::string Key = "cpus detected";
Expand Down Expand Up @@ -540,12 +547,10 @@ int GetNumCPUs() {
}
}
if (f.bad()) {
std::cerr << "Failure reading /proc/cpuinfo\n";
return -1;
PrintErrorAndDie("Failure reading /proc/cpuinfo");
}
if (!f.eof()) {
std::cerr << "Failed to read to end of /proc/cpuinfo\n";
return -1;
PrintErrorAndDie("Failed to read to end of /proc/cpuinfo");
}
f.close();

Expand All @@ -554,7 +559,7 @@ int GetNumCPUs() {
"CPU ID assignments in /proc/cpuinfo seem messed up."
" This is usually caused by a bad BIOS.\n");
}
return num_cpus;
return CheckNumCPUs(num_cpus);
#endif
BENCHMARK_UNREACHABLE();
}
Expand Down

0 comments on commit ee974be

Please sign in to comment.