From 2e16afc3fd53586f9949aa347c4bb909d15523a5 Mon Sep 17 00:00:00 2001 From: dominic <510002+dmah42@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:21:47 +0000 Subject: [PATCH] add back /proc/cpuinfo as a fallback for some platforms (#1918) --- src/sysinfo.cc | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/sysinfo.cc b/src/sysinfo.cc index 2787e87c8..4fb32615b 100644 --- a/src/sysinfo.cc +++ b/src/sysinfo.cc @@ -508,6 +508,55 @@ int GetNumCPUsImpl() { hardware_threads.max_hthreads = 1; } return hardware_threads.max_hthreads; +#else + // Fallback for platforms (such as WASM) that aren't covered above. + 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; + } +#if defined(__alpha__) + const std::string Key = "cpus detected"; +#else + const std::string Key = "processor"; +#endif + std::string ln; + while (std::getline(f, ln)) { + if (ln.empty()) continue; + std::size_t split_idx = ln.find(':'); + std::string value; +#if defined(__s390__) + // s390 has another format in /proc/cpuinfo + // it needs to be parsed differently + if (split_idx != std::string::npos) + value = ln.substr(Key.size() + 1, split_idx - Key.size() - 1); +#else + if (split_idx != std::string::npos) value = ln.substr(split_idx + 1); +#endif + if (ln.size() >= Key.size() && ln.compare(0, Key.size(), Key) == 0) { + num_cpus++; + if (!value.empty()) { + const int cur_id = benchmark::stoi(value); + max_id = std::max(cur_id, max_id); + } + } + } + if (f.bad()) { + PrintErrorAndDie("Failure reading /proc/cpuinfo"); + } + if (!f.eof()) { + PrintErrorAndDie("Failed to read to end of /proc/cpuinfo"); + } + f.close(); + + if ((max_id + 1) != num_cpus) { + fprintf(stderr, + "CPU ID assignments in /proc/cpuinfo seem messed up." + " This is usually caused by a bad BIOS.\n"); + } + return num_cpus; #endif BENCHMARK_UNREACHABLE(); } @@ -516,7 +565,7 @@ int GetNumCPUs() { int num_cpus = GetNumCPUsImpl(); if (num_cpus < 1) { std::cerr << "Unable to extract number of CPUs.\n"; - /* There is at least one CPU which we run on. */ + // There must be at least one CPU on which we're running. num_cpus = 1; } return num_cpus;