diff options
author | Arjan van de Ven <arjan@linux.intel.com> | 2010-08-11 16:21:59 -0400 |
---|---|---|
committer | Arjan van de Ven <arjan@linux.intel.com> | 2010-08-11 16:21:59 -0400 |
commit | 3b703844d9a56b3fa1054075b7de08bfc9ef1ca3 (patch) | |
tree | 5d358bcdb164fa4b28ac298463d7b59e2124098d /cpu | |
parent | 97f6c8c54b523a0ba238101dbf2935f6f70e6e77 (diff) | |
download | powertop-3b703844d9a56b3fa1054075b7de08bfc9ef1ca3.tar.gz |
make sure time is passed through everything
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/abstract_cpu.cpp | 25 | ||||
-rw-r--r-- | cpu/cpu.cpp | 30 | ||||
-rw-r--r-- | cpu/cpu.h | 12 |
3 files changed, 56 insertions, 11 deletions
diff --git a/cpu/abstract_cpu.cpp b/cpu/abstract_cpu.cpp index 8eb6d88..885fc4f 100644 --- a/cpu/abstract_cpu.cpp +++ b/cpu/abstract_cpu.cpp @@ -269,3 +269,28 @@ void abstract_cpu::update_pstate(uint64_t freq, const char *human_name, uint64_t state->time_before += duration; state->before_count += count; } + + +void abstract_cpu::calculate_freq(uint64_t time) +{ + uint64_t freq = 0; + bool is_idle = true; + unsigned int i; + + /* calculate the maximum frequency of all children */ + for (i = 0; i < children.size(); i++) + if (children[i]) { + uint64_t f = 0; + if (!children[i]->idle) { + f = children[i]->current_frequency; + is_idle = false; + } + if (f > freq) + f = freq; + } + + current_frequency = freq; + idle = is_idle; + if (parent) + parent->calculate_freq(time); +}
\ No newline at end of file diff --git a/cpu/cpu.cpp b/cpu/cpu.cpp index f3b8f67..7edd849 100644 --- a/cpu/cpu.cpp +++ b/cpu/cpu.cpp @@ -18,7 +18,7 @@ static class perf_bundle * perf_events; class perf_power_bundle: public perf_bundle { - virtual void handle_trace_point(int type, void *trace, int cpu); + virtual void handle_trace_point(int type, void *trace, int cpu, uint64_t time); }; @@ -104,6 +104,7 @@ static void handle_one_cpu(unsigned int number, char *vendor, int family, int mo } package = system_level.children[package_number]; + package->parent = &system_level; if (package->children.size() <= core_number) package->children.resize(core_number + 1); @@ -114,6 +115,7 @@ static void handle_one_cpu(unsigned int number, char *vendor, int family, int mo } core = package->children[core_number]; + core->parent = package; if (core->children.size() <= number) core->children.resize(number + 1, NULL); @@ -122,7 +124,8 @@ static void handle_one_cpu(unsigned int number, char *vendor, int family, int mo core->childcount++; } - cpu = core->children[number]; + cpu = core->children[number]; + cpu->parent = core; if (number >= all_cpus.size()) all_cpus.resize(number + 1, NULL); @@ -405,25 +408,30 @@ struct power_entry { }; -void perf_power_bundle::handle_trace_point(int type, void *trace, int cpu) +void perf_power_bundle::handle_trace_point(int type, void *trace, int cpunr, uint64_t time) { const char *event_name; + class abstract_cpu *cpu; if (type >= (int)event_names.size()) return; event_name = event_names[type]; - if (strcmp(event_name, "power:power_frequency")==0) { - struct power_entry *pe = (struct power_entry *)trace; - printf("CPU %i new frequency is %lli\n", cpu, pe->value); + if (cpunr >= (int)all_cpus.size()) { + cout << "INVALID cpu nr in handle_trace_point\n"; + return; } - if (strcmp(event_name, "power:power_start")==0) { + + cpu = all_cpus[cpunr]; + + if (strcmp(event_name, "power:power_frequency")==0) { struct power_entry *pe = (struct power_entry *)trace; - printf("CPU %i new CSTATE is %lli\n", cpu, pe->value); - } - if (strcmp(event_name, "power:power_end")==0) { - printf("CPU %i is no longer idle\n", cpu); + cpu->change_freq(time, pe->value); } + if (strcmp(event_name, "power:power_start")==0) + cpu->go_idle(time); + if (strcmp(event_name, "power:power_end")==0) + cpu->go_unidle(time); } void process_cpu_data(void) @@ -55,10 +55,16 @@ protected: uint64_t max_minus_one_frequency; public: int childcount; + bool idle; + int current_frequency; + vector<class abstract_cpu *> children; vector<struct idle_state *> cstates; vector<struct frequency *> pstates; + class abstract_cpu *parent; + + void set_number(int number, int cpu) {this->number = number; this->first_cpu = cpu;}; virtual void measurement_start(void); @@ -89,6 +95,12 @@ public: virtual char * fill_pstate_name(int line_nr, char *buffer) { return buffer;}; virtual int has_pstate_level(int level); + /* 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);}; + }; extern vector<class abstract_cpu *> all_cpus; |