summaryrefslogtreecommitdiffstats
path: root/src/process/timer.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/process/timer.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/process/timer.cpp b/src/process/timer.cpp
new file mode 100644
index 0000000..5d9d2f8
--- /dev/null
+++ b/src/process/timer.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2010, Intel Corporation
+ *
+ * This file is part of PowerTOP
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * Authors:
+ * Arjan van de Ven <arjan@linux.intel.com>
+ */
+#include <map>
+#include <utility>
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "timer.h"
+#include "../lib.h"
+#include "process.h"
+
+using namespace std;
+
+static bool timer_is_deferred(const char *handler)
+{
+ FILE *file;
+ bool ret = false;
+ char line[4096];
+
+ file = fopen("/proc/timer_stats", "r");
+ if (!file) {
+ return ret;
+ }
+
+ while (!feof(file)) {
+ if (fgets(line, 4096, file) == NULL)
+ break;
+ if (strstr(line, handler)) {
+ ret = (strstr(line, "D,") != NULL);
+ if (ret == true)
+ break;
+ }
+ }
+ fclose(file);
+ return ret;
+}
+
+timer::timer(unsigned long address) : power_consumer()
+{
+ pt_strcpy(handler, kernel_function(address));
+ raw_count = 0;
+ deferred = timer_is_deferred(handler);
+}
+
+
+static map<unsigned long, class timer *> all_timers;
+static map<unsigned long, uint64_t> running_since;
+
+void timer::fire(uint64_t time, uint64_t timer_struct)
+{
+ running_since[timer_struct] = time;
+}
+
+uint64_t timer::done(uint64_t time, uint64_t timer_struct)
+{
+ int64_t delta;
+
+ if (running_since.find(timer_struct) == running_since.end())
+ return ~0ULL;
+
+ if (running_since[timer_struct] > time)
+ return 0;
+
+ delta = time - running_since[timer_struct];
+
+ accumulated_runtime += delta;
+
+ raw_count++;
+
+ return delta;
+}
+
+double timer::usage_summary(void)
+{
+ double t;
+ t = (accumulated_runtime - child_runtime) / 1000000.0 / measurement_time / 10;
+ return t;
+}
+
+const char * timer::usage_units_summary(void)
+{
+ return "%";
+}
+
+
+
+static void add_timer(const pair<unsigned long, class timer*>& elem)
+{
+ all_power.push_back(elem.second);
+}
+
+void all_timers_to_all_power(void)
+{
+ for_each(all_timers.begin(), all_timers.end(), add_timer);
+
+}
+
+
+const char * timer::description(void)
+{
+ if (child_runtime > accumulated_runtime)
+ child_runtime = 0;
+
+ snprintf(desc, sizeof(desc), "%s", handler);
+ return desc;
+}
+
+
+class timer * find_create_timer(uint64_t func)
+{
+ class timer * timer;
+ if (all_timers.find(func) != all_timers.end())
+ return all_timers[func];
+
+ timer = new class timer(func);
+ all_timers[func] = timer;
+ return timer;
+
+}
+
+void clear_timers(void)
+{
+ std::map<unsigned long, class timer *>::iterator it = all_timers.begin();
+ while (it != all_timers.end()) {
+ delete it->second;
+ all_timers.erase(it);
+ it = all_timers.begin();
+ }
+ running_since.clear();
+}
+
+bool timer::is_deferred(void)
+{
+ return deferred;
+}