| /* |
| * 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; |
| uint64_t max_minus_one_frequency; |
| public: |
| uint64_t last_stamp; |
| uint64_t total_stamp; |
| int number; |
| int childcount; |
| const char* name; |
| bool idle, old_idle; |
| 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; |
| |
| |
| void set_number(int _number, int cpu) {this->number = _number; this->first_cpu = cpu;}; |
| 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; if (parent) parent->calculate_freq(time);}; |
| virtual void go_unidle(uint64_t time) { idle = false; if (parent) parent->calculate_freq(time);};; |
| virtual void change_freq(uint64_t time, int freq) { current_frequency = freq; if (parent) parent->calculate_freq(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 account_freq(uint64_t frequency, uint64_t duration); |
| 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); |
| |
| virtual void change_freq(uint64_t time, int freq); |
| virtual void change_effective_frequency(uint64_t time, uint64_t freq); |
| virtual void go_idle(uint64_t time); |
| virtual void go_unidle(uint64_t time); |
| |
| }; |
| |
| class cpu_core: public abstract_cpu |
| { |
| void account_freq(uint64_t frequency, uint64_t duration); |
| 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;}; |
| virtual void calculate_freq(uint64_t time); |
| virtual void change_effective_frequency(uint64_t time, uint64_t freq); |
| }; |
| |
| class cpu_package: public abstract_cpu |
| { |
| void account_freq(uint64_t frequency, uint64_t duration); |
| 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;}; |
| |
| virtual void calculate_freq(uint64_t time); |
| virtual void change_effective_frequency(uint64_t time, uint64_t freq); |
| |
| }; |
| |
| #include "intel_cpus.h" |
| |
| 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 |