From fc8408b601e271ed7da5017827cc2e99d816ada9 Mon Sep 17 00:00:00 2001
From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>
Date: Thu, 31 Aug 2017 17:01:44 +0200
Subject: [PATCH] Provide TSC frequency regardless of dmesg availability

---
 dune/perftool/common/tsc.cc | 40 +++++++++++++++++++++++++++++++++++--
 dune/perftool/common/tsc.hh |  4 ++++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/dune/perftool/common/tsc.cc b/dune/perftool/common/tsc.cc
index 3459b95f..999eee11 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 207ec54e..c0027222 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
     {
 
-- 
GitLab