summaryrefslogtreecommitdiffstats
path: root/src/cpu/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/cpu.h')
-rw-r--r--src/cpu/cpu.h234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
new file mode 100644
index 0000000..9114764
--- /dev/null
+++ b/src/cpu/cpu.h
@@ -0,0 +1,234 @@
+/*
+ * 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>
+ */
+
+#ifndef __INCLUDE_GUARD_CPUDEV_H
+#define __INCLUDE_GUARD_CPUDEV_H
+
+#include <iostream>
+#include <vector>
+#include <string>
+#include <stdint.h>
+#include <sys/time.h>
+
+using namespace std;
+
+class abstract_cpu;
+
+#define LEVEL_C0 -1
+#define LEVEL_HEADER -2
+
+#define PSTATE 1
+#define CSTATE 2
+
+struct idle_state {
+ char linux_name[16]; /* state0 etc.. cpuidle name */
+ char human_name[32];
+
+ uint64_t usage_before;
+ uint64_t usage_after;
+ uint64_t usage_delta;
+
+ uint64_t duration_before;
+ uint64_t duration_after;
+ uint64_t duration_delta;
+
+ int before_count;
+ int after_count;
+
+ int line_level;
+};
+
+struct frequency {
+ char human_name[32];
+ int line_level;
+
+ uint64_t freq;
+
+ uint64_t time_after;
+ uint64_t time_before;
+
+ int before_count;
+ int after_count;
+
+ double display_value;
+};
+
+class abstract_cpu
+{
+protected:
+ int first_cpu;
+ struct timeval stamp_before, stamp_after;
+ double time_factor;
+ uint64_t max_frequency = 0;
+ uint64_t max_minus_one_frequency = 0;
+
+ virtual void account_freq(uint64_t frequency, uint64_t duration);
+ virtual void freq_updated(uint64_t time);
+
+public:
+ uint64_t last_stamp;
+ uint64_t total_stamp;
+ int number;
+ int childcount;
+ const char* name;
+ bool idle, old_idle, has_intel_MSR;
+ uint64_t current_frequency;
+ uint64_t effective_frequency;
+
+ vector<class abstract_cpu *> children;
+ vector<struct idle_state *> cstates;
+ vector<struct frequency *> pstates;
+
+ virtual ~abstract_cpu();
+
+ class abstract_cpu *parent;
+
+
+ int get_first_cpu() { return first_cpu; }
+ void set_number(int _number, int cpu) {this->number = _number; this->first_cpu = cpu;};
+ void set_intel_MSR(bool _bool_value) {this->has_intel_MSR = _bool_value;};
+ void set_type(const char* _name) {this->name = _name;};
+ int get_number(void) { return number; };
+ const char* get_type(void) { return name; };
+
+ virtual void measurement_start(void);
+ virtual void measurement_end(void);
+
+ virtual int can_collapse(void) { return 0;};
+
+
+ /* C state related methods */
+
+ void insert_cstate(const char *linux_name, const char *human_name, uint64_t usage, uint64_t duration, int count, int level = -1);
+ void update_cstate(const char *linux_name, const char *human_name, uint64_t usage, uint64_t duration, int count, int level = -1);
+ void finalize_cstate(const char *linux_name, uint64_t usage, uint64_t duration, int count);
+
+ virtual int has_cstate_level(int level);
+
+ virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator="") { return buffer;};
+ virtual char * fill_cstate_percentage(int line_nr, char *buffer) { return buffer; };
+ virtual char * fill_cstate_time(int line_nr, char *buffer) { return buffer; };
+ virtual char * fill_cstate_name(int line_nr, char *buffer) { return buffer;};
+
+
+ /* P state related methods */
+ void insert_pstate(uint64_t freq, const char *human_name, uint64_t duration, int count);
+ void update_pstate(uint64_t freq, const char *human_name, uint64_t duration, int count);
+ void finalize_pstate(uint64_t freq, uint64_t duration, int count);
+
+
+ virtual char * fill_pstate_line(int line_nr, char *buffer) { return buffer;};
+ virtual char * fill_pstate_name(int line_nr, char *buffer) { return buffer;};
+ virtual int has_pstate_level(int level);
+ virtual int has_pstates(void) { return 1; };
+
+ /* Frequency micro accounting methods */
+ virtual void calculate_freq(uint64_t time);
+ virtual void go_idle(uint64_t time) { idle = true; freq_updated(time); }
+ virtual void go_unidle(uint64_t time) { idle = false; freq_updated(time); }
+ virtual void change_freq(uint64_t time, int freq) { current_frequency = freq; freq_updated(time); }
+
+ virtual void change_effective_frequency(uint64_t time, uint64_t freq);
+
+ virtual void wiggle(void);
+
+ virtual uint64_t total_pstate_time(void);
+
+ virtual void validate(void);
+ virtual void reset_pstate_data(void);
+};
+
+extern vector<class abstract_cpu *> all_cpus;
+
+class cpu_linux: public abstract_cpu
+{
+ void parse_pstates_start(void);
+ void parse_cstates_start(void);
+ void parse_pstates_end(void);
+ void parse_cstates_end(void);
+
+public:
+ virtual void measurement_start(void);
+ virtual void measurement_end(void);
+
+ virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator="");
+ virtual char * fill_cstate_name(int line_nr, char *buffer);
+ virtual char * fill_cstate_percentage(int line_nr, char *buffer);
+ virtual char * fill_cstate_time(int line_nr, char *buffer);
+
+ virtual char * fill_pstate_line(int line_nr, char *buffer);
+ virtual char * fill_pstate_name(int line_nr, char *buffer);
+};
+
+class cpu_core: public abstract_cpu
+{
+public:
+ virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator="");
+ virtual char * fill_cstate_name(int line_nr, char *buffer);
+
+ virtual char * fill_pstate_line(int line_nr, char *buffer);
+ virtual char * fill_pstate_name(int line_nr, char *buffer);
+
+ virtual int can_collapse(void) { return childcount == 1;};
+};
+
+class cpu_package: public abstract_cpu
+{
+protected:
+ virtual void freq_updated(uint64_t time);
+public:
+ virtual char * fill_cstate_line(int line_nr, char *buffer, const char *separator="");
+ virtual char * fill_cstate_name(int line_nr, char *buffer);
+
+ virtual char * fill_pstate_line(int line_nr, char *buffer);
+ virtual char * fill_pstate_name(int line_nr, char *buffer);
+ virtual int can_collapse(void) { return childcount == 1;};
+};
+
+extern void enumerate_cpus(void);
+
+extern void report_display_cpu_pstates(void);
+extern void report_display_cpu_cstates(void);
+
+
+
+extern void display_cpu_cstates(const char *start= "",
+ const char *end = "",
+ const char *linestart = "",
+ const char *separator = "| ",
+ const char *lineend = "\n");
+
+extern void w_display_cpu_cstates(void);
+extern void w_display_cpu_pstates(void);
+
+
+extern void start_cpu_measurement(void);
+extern void end_cpu_measurement(void);
+extern void process_cpu_data(void);
+extern void end_cpu_data(void);
+extern void clear_cpu_data(void);
+extern void clear_all_cpus(void);
+
+#endif