diff --git a/dune/perftool/common/tsc.cc b/dune/perftool/common/tsc.cc index 3459b95ff8b9cf3d493f32896193ab0215e9c0b1..999eee11a6900800fa11745bb9d3bdb39f9c468b 100644 --- a/dune/perftool/common/tsc.cc +++ b/dune/perftool/common/tsc.cc @@ -23,7 +23,7 @@ namespace Dune { #if __linux__ - TSC::Counter get_tsc_frequency() + TSC::Counter get_tsc_frequency_from_dmesg() { int pipe_fds[2]; if (pipe(pipe_fds) < 0) @@ -99,7 +99,7 @@ namespace Dune { DUNE_THROW(TSCError,"Child process failed with return status " << WEXITSTATUS(status)); if (result < 0) - DUNE_THROW(TSCError,"Could not find TSC frequency information in kernel log"); + DUNE_THROW(TSCNotInKernelLog,"Could not find TSC frequency information in kernel log"); } @@ -109,6 +109,42 @@ namespace Dune { } + TSC::Counter get_tsc_frequency_from_cpuinfo() + { + double result = -1.0; + try { + auto cpuinfo = std::ifstream("/proc/cpuinfo"); + auto re = std::regex("bogomips\\s:\\s(\\d+\\.\\d+)$"); + + using std::getline; + for (std::string line ; getline(cpuinfo,line) ; ) + { + if (auto match = std::smatch() ; std::regex_match(line,match,re)) + { + result = 5e5 * std::stod(match[1].str()); + break; + } + } + } + catch(std::exception& e) { + DUNE_THROW(TSCError,"error getting TSC frequency from /proc/cpuinfo: " << e.what()); + } + + if (result < 0) + DUNE_THROW(TSCError,"could not find bogomips value in /proc/cpuinfo"); + + return result; + } + + TSC::Counter get_tsc_frequency() + { + try { + return get_tsc_frequency_from_dmesg(); + } + catch (TSCNotInKernelLog&) { + return get_tsc_frequency_from_cpuinfo(); + } + } #elif __APPLE__ diff --git a/dune/perftool/common/tsc.hh b/dune/perftool/common/tsc.hh index 207ec54ee2fac2a1cad72b877c55b91f6f325d6c..c002722269aa580f28006d14f8049dddb5680987 100644 --- a/dune/perftool/common/tsc.hh +++ b/dune/perftool/common/tsc.hh @@ -11,6 +11,10 @@ namespace Dune { : public Exception {}; + class TSCNotInKernelLog + : public TSCError + {}; + class TSC {