/* * 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 */ #ifndef __INCLUDE_GUARD_CPUDEV_H #define __INCLUDE_GUARD_CPUDEV_H #include #include #include #include #include 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; bool idle, old_idle; uint64_t current_frequency; uint64_t effective_frequency; vector children; vector cstates; vector pstates; virtual ~abstract_cpu() {}; class abstract_cpu *parent; void set_number(int _number, int cpu) {this->number = _number; this->first_cpu = cpu;}; 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_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 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_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