aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJilin Zhou <jilinzhou@hotmail.com>2019-02-28 05:42:44 -0500
committerDominic Hamon <dominichamon@users.noreply.github.com>2019-02-28 10:42:44 +0000
commitd205ead299c7cddd5e1bc3478d57ad4320a4a53c (patch)
treeb83be030c39671c740d06c778f2e30b3f8443ebf
parent0ae233ab23c560547bf85ce1346580966e799861 (diff)
downloadgoogle-benchmark-d205ead299c7cddd5e1bc3478d57ad4320a4a53c.tar.gz
[#774] implement GetNumCPUs(), GetCPUCyclesPerSecond(), and GetCacheSizes() (#775)
- On qnx platform, cpu and cache info is stored in a syspage struct which is different from other OS platform. - The fix has been verified on an aarch64 target running qnx 7.0. Fixes #774
-rw-r--r--src/sysinfo.cc47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/sysinfo.cc b/src/sysinfo.cc
index 55953a0..953c170 100644
--- a/src/sysinfo.cc
+++ b/src/sysinfo.cc
@@ -37,6 +37,9 @@
#if defined(BENCHMARK_OS_SOLARIS)
#include <kstat.h>
#endif
+#if defined(BENCHMARK_OS_QNX)
+#include <sys/syspage.h>
+#endif
#include <algorithm>
#include <array>
@@ -209,6 +212,9 @@ bool ReadFromFile(std::string const& fname, ArgT* arg) {
bool CpuScalingEnabled(int num_cpus) {
// We don't have a valid CPU count, so don't even bother.
if (num_cpus <= 0) return false;
+#ifdef BENCHMARK_OS_QNX
+ return false;
+#endif
#ifndef BENCHMARK_OS_WINDOWS
// On Linux, the CPUfreq subsystem exposes CPU information as files on the
// local file system. If reading the exported files fails, then we may not be
@@ -356,6 +362,40 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizesWindows() {
}
return res;
}
+#elif BENCHMARK_OS_QNX
+std::vector<CPUInfo::CacheInfo> GetCacheSizesQNX() {
+ std::vector<CPUInfo::CacheInfo> res;
+ struct cacheattr_entry *cache = SYSPAGE_ENTRY(cacheattr);
+ uint32_t const elsize = SYSPAGE_ELEMENT_SIZE(cacheattr);
+ int num = SYSPAGE_ENTRY_SIZE(cacheattr) / elsize ;
+ for(int i = 0; i < num; ++i ) {
+ CPUInfo::CacheInfo info;
+ switch (cache->flags){
+ case CACHE_FLAG_INSTR :
+ info.type = "Instruction";
+ info.level = 1;
+ break;
+ case CACHE_FLAG_DATA :
+ info.type = "Data";
+ info.level = 1;
+ break;
+ case CACHE_FLAG_UNIFIED :
+ info.type = "Unified";
+ info.level = 2;
+ case CACHE_FLAG_SHARED :
+ info.type = "Shared";
+ info.level = 3;
+ default :
+ continue;
+ break;
+ }
+ info.size = cache->line_size * cache->num_lines;
+ info.num_sharing = 0;
+ res.push_back(std::move(info));
+ cache = SYSPAGE_ARRAY_ADJ_OFFSET(cacheattr, cache, elsize);
+ }
+ return res;
+}
#endif
std::vector<CPUInfo::CacheInfo> GetCacheSizes() {
@@ -363,6 +403,8 @@ std::vector<CPUInfo::CacheInfo> GetCacheSizes() {
return GetCacheSizesMacOSX();
#elif defined(BENCHMARK_OS_WINDOWS)
return GetCacheSizesWindows();
+#elif defined(BENCHMARK_OS_QNX)
+ return GetCacheSizesQNX();
#else
return GetCacheSizesFromKVFS();
#endif
@@ -423,6 +465,8 @@ int GetNumCPUs() {
strerror(errno));
}
return NumCPU;
+#elif defined(BENCHMARK_OS_QNX)
+ return static_cast<int>(_syspage_ptr->num_cpu);
#else
int NumCPUs = 0;
int MaxID = -1;
@@ -602,6 +646,9 @@ double GetCPUCyclesPerSecond() {
double clock_hz = knp->value.ui64;
kstat_close(kc);
return clock_hz;
+#elif defined (BENCHMARK_OS_QNX)
+ return static_cast<double>((int64_t)(SYSPAGE_ENTRY(cpuinfo)->speed) *
+ (int64_t)(1000 * 1000));
#endif
// If we've fallen through, attempt to roughly estimate the CPU clock rate.
const int estimate_time_ms = 1000;