diff --git a/README.md b/README.md index 0fb9024..167bf7a 100644 --- a/README.md +++ b/README.md @@ -936,3 +936,6 @@ sudo cpupower frequency-set --governor powersave * Users must manually link `shlwapi.lib`. Failure to do so may result in unresolved symbols. +### Solaris + +* Users must explicitly link with kstat library (-lkstat compilation flag). diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e22620a..836549e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,6 +34,11 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_link_libraries(benchmark Shlwapi) endif() +# We need extra libraries on Solaris +if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + target_link_libraries(benchmark kstat) +endif() + set(include_install_dir "include") set(lib_install_dir "lib/") set(bin_install_dir "bin/") diff --git a/src/internal_macros.h b/src/internal_macros.h index faa753e..f299722 100644 --- a/src/internal_macros.h +++ b/src/internal_macros.h @@ -60,6 +60,8 @@ #define BENCHMARK_OS_RTEMS 1 #elif defined(__Fuchsia__) #define BENCHMARK_OS_FUCHSIA 1 +#elif defined (__SVR4) && defined (__sun) +#define BENCHMARK_OS_SOLARIS 1 #endif #if !__has_feature(cxx_exceptions) && !defined(__cpp_exceptions) \ diff --git a/src/sysinfo.cc b/src/sysinfo.cc index 2b4e1dd..fdcc95b 100644 --- a/src/sysinfo.cc +++ b/src/sysinfo.cc @@ -32,6 +32,9 @@ #include #endif #endif +#if defined(BENCHMARK_OS_SOLARIS) +#include +#endif #include #include @@ -356,6 +359,15 @@ int GetNumCPUs() { return sysinfo.dwNumberOfProcessors; // number of logical // processors in the current // group +#elif defined(BENCHMARK_OS_SOLARIS) + // Returns -1 in case of a failure. + int NumCPU = sysconf(_SC_NPROCESSORS_ONLN); + if (NumCPU < 0) { + fprintf(stderr, + "sysconf(_SC_NPROCESSORS_ONLN) failed with error: %s\n", + strerror(errno)); + } + return NumCPU; #else int NumCPUs = 0; int MaxID = -1; @@ -495,6 +507,35 @@ double GetCPUCyclesPerSecond() { "~MHz", nullptr, &data, &data_size))) return static_cast((int64_t)data * (int64_t)(1000 * 1000)); // was mhz +#elif defined (BENCHMARK_OS_SOLARIS) + kstat_ctl_t *kc = kstat_open(); + if (!kc) { + std::cerr << "failed to open /dev/kstat\n"; + return -1; + } + kstat_t *ksp = kstat_lookup(kc, (char*)"cpu_info", -1, (char*)"cpu_info0"); + if (!ksp) { + std::cerr << "failed to lookup in /dev/kstat\n"; + return -1; + } + if (kstat_read(kc, ksp, NULL) < 0) { + std::cerr << "failed to read from /dev/kstat\n"; + return -1; + } + kstat_named_t *knp = + (kstat_named_t*)kstat_data_lookup(ksp, (char*)"current_clock_Hz"); + if (!knp) { + std::cerr << "failed to lookup data in /dev/kstat\n"; + return -1; + } + if (knp->data_type != KSTAT_DATA_UINT64) { + std::cerr << "current_clock_Hz is of unexpected data type: " + << knp->data_type << "\n"; + return -1; + } + double clock_hz = knp->value.ui64; + kstat_close(kc); + return clock_hz; #endif // If we've fallen through, attempt to roughly estimate the CPU clock rate. const int estimate_time_ms = 1000; diff --git a/src/timers.cc b/src/timers.cc index 09680c7..893cd38 100644 --- a/src/timers.cc +++ b/src/timers.cc @@ -164,6 +164,10 @@ double ThreadCPUUsage() { // RTEMS doesn't support CLOCK_THREAD_CPUTIME_ID. See // https://github.com/RTEMS/rtems/blob/master/cpukit/posix/src/clockgettime.c return ProcessCPUUsage(); +#elif defined(BENCHMARK_OS_SOLARIS) + struct rusage ru; + if (getrusage(RUSAGE_LWP, &ru) == 0) return MakeTime(ru); + DiagnoseAndExit("getrusage(RUSAGE_LWP, ...) failed"); #elif defined(CLOCK_THREAD_CPUTIME_ID) struct timespec ts; if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts);