| /* |
| * 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 <iostream> |
| #include <fstream> |
| #include <vector> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <ncurses.h> |
| #include <unistd.h> |
| #include "cpu.h" |
| #include "cpudevice.h" |
| #include "../parameters/parameters.h" |
| |
| #include "../perf/perf_bundle.h" |
| #include "../lib.h" |
| #include "../display.h" |
| #include "../report/report.h" |
| #include "../report/report-maker.h" |
| |
| static class abstract_cpu system_level; |
| |
| vector<class abstract_cpu *> all_cpus; |
| |
| static class perf_bundle * perf_events; |
| |
| |
| |
| class perf_power_bundle: public perf_bundle |
| { |
| virtual void handle_trace_point(void *trace, int cpu, uint64_t time); |
| |
| }; |
| |
| |
| static class abstract_cpu * new_package(int package, int cpu, char * vendor, int family, int model) |
| { |
| class abstract_cpu *ret = NULL; |
| class cpudevice *cpudev; |
| char packagename[128]; |
| if (strcmp(vendor, "GenuineIntel") == 0) { |
| if (family == 6) |
| switch (model) { |
| case 0x1A: /* Core i7, Xeon 5500 series */ |
| case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ |
| case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
| case 0x2E: /* Nehalem-EX Xeon */ |
| case 0x2F: /* Westmere-EX Xeon */ |
| case 0x25: /* Westmere */ |
| case 0x27: /* Medfield Atom*/ |
| case 0x2C: /* Westmere */ |
| ret = new class nhm_package; |
| break; |
| case 0x2A: /* SNB */ |
| case 0x2D: /* SNB Xeon */ |
| case 0x3A: /* IVB */ |
| case 0x3C: |
| case 0x3D: /* IVB Xeon */ |
| has_c2c7_res = 1; |
| ret = new class nhm_package; |
| break; |
| } |
| } |
| |
| if (!ret) |
| ret = new class cpu_package; |
| |
| ret->set_number(package, cpu); |
| ret->set_type("Package"); |
| ret->childcount = 0; |
| |
| sprintf(packagename, _("cpu package %i"), cpu); |
| cpudev = new class cpudevice(_("cpu package"), packagename, ret); |
| all_devices.push_back(cpudev); |
| return ret; |
| } |
| |
| static class abstract_cpu * new_core(int core, int cpu, char * vendor, int family, int model) |
| { |
| class abstract_cpu *ret = NULL; |
| |
| if (strcmp(vendor, "GenuineIntel") == 0) { |
| if (family == 6) |
| switch (model) { |
| case 0x1A: /* Core i7, Xeon 5500 series */ |
| case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ |
| case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
| case 0x2E: /* Nehalem-EX Xeon */ |
| case 0x2F: /* Westmere-EX Xeon */ |
| case 0x25: /* Westmere */ |
| case 0x2C: /* Westmere */ |
| case 0x2A: /* SNB */ |
| case 0x2D: /* SNB Xeon */ |
| case 0x3A: /* IVB */ |
| case 0x3C: |
| case 0x3D: /* IVB Xeon */ |
| ret = new class nhm_core; |
| } |
| } |
| |
| if (!ret) |
| ret = new class cpu_core; |
| ret->set_number(core, cpu); |
| ret->childcount = 0; |
| ret->set_type("Core"); |
| |
| return ret; |
| } |
| |
| static class abstract_cpu * new_i965_gpu(void) |
| { |
| class abstract_cpu *ret = NULL; |
| |
| ret = new class i965_core; |
| ret->childcount = 0; |
| ret->set_type("GPU"); |
| |
| return ret; |
| } |
| |
| static class abstract_cpu * new_cpu(int number, char * vendor, int family, int model) |
| { |
| class abstract_cpu * ret = NULL; |
| |
| if (strcmp(vendor, "GenuineIntel") == 0) { |
| if (family == 6) |
| switch (model) { |
| case 0x1A: /* Core i7, Xeon 5500 series */ |
| case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ |
| case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
| case 0x2E: /* Nehalem-EX Xeon */ |
| case 0x2F: /* Westmere-EX Xeon */ |
| case 0x25: /* Westmere */ |
| case 0x2C: /* Westmere */ |
| case 0x2A: /* SNB */ |
| case 0x2D: /* SNB Xeon */ |
| case 0x3A: /* IVB */ |
| case 0x3C: |
| case 0x3D: /* IVB Xeon */ |
| ret = new class nhm_cpu; |
| } |
| } |
| |
| if (!ret) |
| ret = new class cpu_linux; |
| ret->set_number(number, number); |
| ret->set_type("CPU"); |
| ret->childcount = 0; |
| |
| return ret; |
| } |
| |
| |
| |
| |
| static void handle_one_cpu(unsigned int number, char *vendor, int family, int model) |
| { |
| char filename[1024]; |
| ifstream file; |
| unsigned int package_number = 0; |
| unsigned int core_number = 0; |
| class abstract_cpu *package, *core, *cpu; |
| |
| sprintf(filename, "/sys/devices/system/cpu/cpu%i/topology/core_id", number); |
| file.open(filename, ios::in); |
| if (file) { |
| file >> core_number; |
| file.close(); |
| } |
| |
| sprintf(filename, "/sys/devices/system/cpu/cpu%i/topology/physical_package_id", number); |
| file.open(filename, ios::in); |
| if (file) { |
| file >> package_number; |
| if (package_number == (unsigned int) -1) |
| package_number = 0; |
| file.close(); |
| } |
| |
| |
| if (system_level.children.size() <= package_number) |
| system_level.children.resize(package_number + 1, NULL); |
| |
| if (!system_level.children[package_number]) { |
| system_level.children[package_number] = new_package(package_number, number, vendor, family, model); |
| system_level.childcount++; |
| } |
| |
| package = system_level.children[package_number]; |
| package->parent = &system_level; |
| |
| if (package->children.size() <= core_number) |
| package->children.resize(core_number + 1, NULL); |
| |
| if (!package->children[core_number]) { |
| package->children[core_number] = new_core(core_number, number, vendor, family, model); |
| package->childcount++; |
| } |
| |
| core = package->children[core_number]; |
| core->parent = package; |
| |
| if (core->children.size() <= number) |
| core->children.resize(number + 1, NULL); |
| if (!core->children[number]) { |
| core->children[number] = new_cpu(number, vendor, family, model); |
| core->childcount++; |
| } |
| |
| cpu = core->children[number]; |
| cpu->parent = core; |
| |
| if (number >= all_cpus.size()) |
| all_cpus.resize(number + 1, NULL); |
| all_cpus[number] = cpu; |
| } |
| |
| static void handle_i965_gpu(void) |
| { |
| unsigned int core_number = 0; |
| class abstract_cpu *package; |
| |
| |
| package = system_level.children[0]; |
| |
| core_number = package->children.size(); |
| |
| if (package->children.size() <= core_number) |
| package->children.resize(core_number + 1, NULL); |
| |
| if (!package->children[core_number]) { |
| package->children[core_number] = new_i965_gpu(); |
| package->childcount++; |
| } |
| } |
| |
| |
| void enumerate_cpus(void) |
| { |
| ifstream file; |
| char line[1024]; |
| |
| int number = -1; |
| char vendor[128]; |
| int family = 0; |
| int model = 0; |
| |
| file.open("/proc/cpuinfo", ios::in); |
| |
| if (!file) |
| return; |
| /* Not all /proc/cpuinfo include "vendor_id\t". */ |
| vendor[0] = '\0'; |
| |
| while (file) { |
| |
| file.getline(line, sizeof(line)); |
| if (strncmp(line, "vendor_id\t",10) == 0) { |
| char *c; |
| c = strchr(line, ':'); |
| if (c) { |
| c++; |
| if (*c == ' ') |
| c++; |
| strncpy(vendor,c, 127); |
| } |
| } |
| if (strncmp(line, "processor\t",10) == 0) { |
| char *c; |
| c = strchr(line, ':'); |
| if (c) { |
| c++; |
| number = strtoull(c, NULL, 10); |
| } |
| } |
| if (strncmp(line, "cpu family\t",11) == 0) { |
| char *c; |
| c = strchr(line, ':'); |
| if (c) { |
| c++; |
| family = strtoull(c, NULL, 10); |
| } |
| } |
| if (strncmp(line, "model\t",6) == 0) { |
| char *c; |
| c = strchr(line, ':'); |
| if (c) { |
| c++; |
| model = strtoull(c, NULL, 10); |
| } |
| } |
| if (strncasecmp(line, "bogomips\t", 9) == 0) { |
| if (number == -1) { |
| /* Not all /proc/cpuinfo include "processor\t". */ |
| number = 0; |
| } |
| if (number >= 0) { |
| handle_one_cpu(number, vendor, family, model); |
| set_max_cpu(number); |
| number = -2; |
| } |
| } |
| } |
| |
| |
| file.close(); |
| |
| if (access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK) == 0) |
| handle_i965_gpu(); |
| |
| perf_events = new perf_power_bundle(); |
| |
| if (!perf_events->add_event("power:cpu_idle")){ |
| perf_events->add_event("power:power_start"); |
| perf_events->add_event("power:power_end"); |
| } |
| if (!perf_events->add_event("power:cpu_frequency")) |
| perf_events->add_event("power:power_frequency"); |
| |
| } |
| |
| void start_cpu_measurement(void) |
| { |
| perf_events->start(); |
| system_level.measurement_start(); |
| } |
| |
| void end_cpu_measurement(void) |
| { |
| system_level.measurement_end(); |
| perf_events->stop(); |
| } |
| |
| static void expand_string(char *string, unsigned int newlen) |
| { |
| while (strlen(string) < newlen) |
| strcat(string, " "); |
| } |
| |
| static int has_state_level(class abstract_cpu *acpu, int state, int line) |
| { |
| switch (state) { |
| case PSTATE: |
| return acpu->has_pstate_level(line); |
| break; |
| case CSTATE: |
| return acpu->has_cstate_level(line); |
| break; |
| } |
| return 0; |
| } |
| |
| static const char * fill_state_name(class abstract_cpu *acpu, int state, int line, char *buf) |
| { |
| switch (state) { |
| case PSTATE: |
| return acpu->fill_pstate_name(line, buf); |
| break; |
| case CSTATE: |
| return acpu->fill_cstate_name(line, buf); |
| break; |
| } |
| return "-EINVAL"; |
| } |
| |
| static const char * fill_state_line(class abstract_cpu *acpu, int state, int line, |
| char *buf, const char *sep = "") |
| { |
| switch (state) { |
| case PSTATE: |
| return acpu->fill_pstate_line(line, buf); |
| break; |
| case CSTATE: |
| return acpu->fill_cstate_line(line, buf, sep); |
| break; |
| } |
| return "-EINVAL"; |
| } |
| |
| void report_display_cpu_cstates(void) |
| { |
| char buffer[512], buffer2[512]; |
| unsigned int package, core, cpu; |
| int line; |
| class abstract_cpu *_package, * _core, * _cpu; |
| |
| report.begin_section(SECTION_CPUIDLE); |
| report.add_header("Processor Idle state report"); |
| |
| for (package = 0; package < system_level.children.size(); package++) { |
| bool first_core = true; |
| |
| _package = system_level.children[package]; |
| if (!_package) |
| continue; |
| |
| report.begin_table(TABLE_WIDE); |
| for (core = 0; core < _package->children.size(); core++) { |
| _core = _package->children[core]; |
| if (!_core) |
| continue; |
| |
| for (line = LEVEL_HEADER; line < 10; line++) { |
| bool first_cpu = true; |
| |
| if (!_package->has_cstate_level(line)) |
| continue; |
| |
| report.begin_row(); |
| buffer[0] = 0; |
| buffer2[0] = 0; |
| |
| if (line == LEVEL_HEADER) { |
| if (first_core) { |
| report.begin_cell(CELL_FIRST_PACKAGE_HEADER); |
| report.addf(__("Package %i"), _package->get_number()); |
| } else { |
| report.begin_cell(CELL_EMPTY_PACKAGE_HEADER); |
| report.add_empty_cell(); |
| } |
| } else if (first_core) { |
| report.begin_cell(CELL_STATE_NAME); |
| report.add(_package->fill_cstate_name(line, buffer)); |
| report.begin_cell(CELL_PACKAGE_STATE_VALUE); |
| report.add(_package->fill_cstate_line(line, buffer2)); |
| } else { |
| report.begin_cell(CELL_EMPTY_PACKAGE_STATE); |
| report.add_empty_cell(); |
| } |
| |
| report.begin_cell(CELL_SEPARATOR); |
| report.add_empty_cell(); |
| |
| if (!_core->can_collapse()) { |
| buffer[0] = 0; |
| buffer2[0] = 0; |
| |
| if (line == LEVEL_HEADER) { |
| report.begin_cell(CELL_CORE_HEADER); |
| /* Here we need to check for which core type we |
| * are using. Do not use the core type for the |
| * report.addf as it breaks an important macro use |
| * for translation decision making for the reports. |
| */ |
| const char* core_type = _core->get_type(); |
| if (core_type != NULL) { |
| if (strcmp(core_type, "Core") == 0 ) { |
| report.addf(__("Core %i"), _core->get_number()); |
| } else { |
| report.addf(__("GPU %i"), _core->get_number()); |
| } |
| } |
| } else { |
| report.begin_cell(CELL_STATE_NAME); |
| report.add(_core->fill_cstate_name(line, buffer)); |
| report.begin_cell(CELL_CORE_STATE_VALUE); |
| report.add(_core->fill_cstate_line(line, buffer2)); |
| } |
| } |
| |
| report.begin_cell(CELL_SEPARATOR); |
| report.add_empty_cell(); |
| |
| for (cpu = 0; cpu < _core->children.size(); cpu++) { |
| _cpu = _core->children[cpu]; |
| if (!_cpu) |
| continue; |
| |
| report.set_cpu_number(cpu); |
| if (line == LEVEL_HEADER) { |
| report.begin_cell(CELL_CPU_CSTATE_HEADER); |
| report.addf(__("CPU %i"), _cpu->get_number()); |
| continue; |
| } |
| |
| if (first_cpu) { |
| report.begin_cell(CELL_STATE_NAME); |
| report.add(_cpu->fill_cstate_name(line, buffer)); |
| first_cpu = false; |
| } |
| |
| buffer[0] = 0; |
| report.begin_cell(CELL_CPU_STATE_VALUE); |
| report.add(_cpu->fill_cstate_percentage(line, buffer)); |
| report.begin_cell(CELL_CPU_STATE_VALUE); |
| if (line != LEVEL_C0) |
| report.add(_cpu->fill_cstate_time(line, buffer)); |
| else |
| report.add_empty_cell(); |
| } |
| } |
| |
| first_core = false; |
| } |
| } |
| } |
| |
| void report_display_cpu_pstates(void) |
| { |
| char buffer[512], buffer2[512]; |
| unsigned int package, core, cpu; |
| int line; |
| class abstract_cpu *_package, * _core, * _cpu; |
| unsigned int i, pstates_num; |
| |
| for (i = 0, pstates_num = 0; i < all_cpus.size(); i++) |
| if (all_cpus[i] && all_cpus[i]->pstates.size() > pstates_num) |
| pstates_num = all_cpus[i]->pstates.size(); |
| |
| report.begin_section(SECTION_CPUFREQ); |
| report.add_header("Processor Frequency Report"); |
| |
| for (package = 0; package < system_level.children.size(); package++) { |
| bool first_core = true; |
| |
| _package = system_level.children[package]; |
| if (!_package) |
| continue; |
| |
| report.begin_table(TABLE_WIDE); |
| for (core = 0; core < _package->children.size(); core++) { |
| _core = _package->children[core]; |
| if (!_core) |
| continue; |
| |
| if (!_core->has_pstates()) |
| continue; |
| |
| for (line = LEVEL_HEADER; line < (int)pstates_num; line++) { |
| bool first_cpu = true; |
| |
| if (!_package->has_pstate_level(line)) |
| continue; |
| |
| report.begin_row(); |
| |
| buffer[0] = 0; |
| buffer2[0] = 0; |
| if (first_core) { |
| if (line == LEVEL_HEADER) { |
| report.begin_cell(CELL_FIRST_PACKAGE_HEADER); |
| report.addf(__("Package %i"), _package->get_number()); |
| } else { |
| report.begin_cell(CELL_STATE_NAME); |
| report.add(_package->fill_pstate_name(line, buffer)); |
| report.begin_cell(CELL_PACKAGE_STATE_VALUE); |
| report.add(_package->fill_pstate_line(line, buffer2)); |
| } |
| } else { |
| report.begin_cell(CELL_EMPTY_PACKAGE_STATE); |
| report.add_empty_cell(); |
| } |
| |
| report.begin_cell(CELL_SEPARATOR); |
| report.add_empty_cell(); |
| |
| if (!_core->can_collapse()) { |
| buffer[0] = 0; |
| buffer2[0] = 0; |
| if (line == LEVEL_HEADER) { |
| report.begin_cell(CELL_CORE_HEADER); |
| report.addf(__("Core %i"), _core->get_number()); |
| } else { |
| report.begin_cell(CELL_STATE_NAME); |
| report.add(_core->fill_pstate_name(line, buffer)); |
| report.begin_cell(CELL_PACKAGE_STATE_VALUE); |
| report.add(_core->fill_pstate_line(line, buffer2)); |
| } |
| } |
| |
| report.begin_cell(CELL_SEPARATOR); |
| report.add_empty_cell(); |
| |
| for (cpu = 0; cpu < _core->children.size(); cpu++) { |
| buffer[0] = 0; |
| _cpu = _core->children[cpu]; |
| if (!_cpu) |
| continue; |
| |
| report.set_cpu_number(cpu); |
| if (line == LEVEL_HEADER) { |
| report.begin_cell(CELL_CPU_PSTATE_HEADER); |
| report.addf(__("CPU %i"), _cpu->get_number()); |
| continue; |
| } |
| |
| if (first_cpu) { |
| report.begin_cell(CELL_STATE_NAME); |
| report.add(_cpu->fill_pstate_name(line, buffer)); |
| first_cpu = false; |
| } |
| |
| buffer[0] = 0; |
| report.begin_cell(CELL_CPU_STATE_VALUE); |
| report.add(_cpu->fill_pstate_line(line, buffer)); |
| } |
| } |
| |
| first_core = false; |
| } |
| } |
| } |
| |
| void impl_w_display_cpu_states(int state) |
| { |
| WINDOW *win; |
| char buffer[128]; |
| char linebuf[1024]; |
| unsigned int package, core, cpu; |
| int line; |
| class abstract_cpu *_package, * _core, * _cpu; |
| int ctr = 0; |
| |
| if (state == PSTATE) |
| win = get_ncurses_win("Frequency stats"); |
| else |
| win = get_ncurses_win("Idle stats"); |
| |
| if (!win) |
| return; |
| |
| wclear(win); |
| wmove(win, 2,0); |
| |
| for (package = 0; package < system_level.children.size(); package++) { |
| int first_pkg = 0; |
| _package = system_level.children[package]; |
| if (!_package) |
| continue; |
| |
| for (core = 0; core < _package->children.size(); core++) { |
| _core = _package->children[core]; |
| if (!_core) |
| continue; |
| if (!_core->has_pstates() && state == PSTATE) |
| continue; |
| |
| |
| for (line = LEVEL_HEADER; line < 10; line++) { |
| int first = 1; |
| ctr = 0; |
| linebuf[0] = 0; |
| |
| if (!has_state_level(_package, state, line)) |
| continue; |
| |
| buffer[0] = 0; |
| if (first_pkg == 0) { |
| strcat(linebuf, fill_state_name(_package, state, line, buffer)); |
| expand_string(linebuf, ctr + 10); |
| strcat(linebuf, fill_state_line(_package, state, line, buffer)); |
| } |
| ctr += 20; |
| expand_string(linebuf, ctr); |
| |
| strcat(linebuf, "| "); |
| ctr += strlen("| "); |
| |
| if (!_core->can_collapse()) { |
| buffer[0] = 0; |
| strcat(linebuf, fill_state_name(_core, state, line, buffer)); |
| expand_string(linebuf, ctr + 10); |
| strcat(linebuf, fill_state_line(_core, state, line, buffer)); |
| ctr += 20; |
| expand_string(linebuf, ctr); |
| |
| strcat(linebuf, "| "); |
| ctr += strlen("| "); |
| } |
| |
| for (cpu = 0; cpu < _core->children.size(); cpu++) { |
| _cpu = _core->children[cpu]; |
| if (!_cpu) |
| continue; |
| |
| if (first == 1) { |
| strcat(linebuf, fill_state_name(_cpu, state, line, buffer)); |
| expand_string(linebuf, ctr + 10); |
| first = 0; |
| ctr += 12; |
| } |
| buffer[0] = 0; |
| strcat(linebuf, fill_state_line(_cpu, state, line, buffer)); |
| ctr += 10; |
| expand_string(linebuf, ctr); |
| |
| } |
| strcat(linebuf, "\n"); |
| wprintw(win, "%s", linebuf); |
| } |
| wprintw(win, "\n"); |
| first_pkg++; |
| } |
| } |
| } |
| |
| void w_display_cpu_pstates(void) |
| { |
| impl_w_display_cpu_states(PSTATE); |
| } |
| |
| void w_display_cpu_cstates(void) |
| { |
| impl_w_display_cpu_states(CSTATE); |
| } |
| |
| struct power_entry { |
| #ifndef __i386__ |
| int dummy; |
| #endif |
| int64_t type; |
| int64_t value; |
| } __attribute__((packed)); |
| |
| |
| void perf_power_bundle::handle_trace_point(void *trace, int cpunr, uint64_t time) |
| { |
| struct event_format *event; |
| struct pevent_record rec; /* holder */ |
| class abstract_cpu *cpu; |
| int type; |
| |
| rec.data = trace; |
| |
| type = pevent_data_type(perf_event::pevent, &rec); |
| event = pevent_find_event(perf_event::pevent, type); |
| |
| if (!event) |
| return; |
| |
| if (cpunr >= (int)all_cpus.size()) { |
| cout << "INVALID cpu nr in handle_trace_point\n"; |
| return; |
| } |
| |
| cpu = all_cpus[cpunr]; |
| |
| #if 0 |
| unsigned int i; |
| printf("Time is %llu \n", time); |
| for (i = 0; i < system_level.children.size(); i++) |
| if (system_level.children[i]) |
| system_level.children[i]->validate(); |
| #endif |
| unsigned long long val; |
| int ret; |
| if (strcmp(event->name, "cpu_idle")==0) { |
| |
| ret = pevent_get_field_val(NULL, event, "state", &rec, &val, 0); |
| if (ret < 0) { |
| fprintf(stderr, _("cpu_idle event returned no state?\n")); |
| exit(-1); |
| } |
| |
| if (val == 4294967295) |
| cpu->go_unidle(time); |
| else |
| cpu->go_idle(time); |
| } |
| |
| if (strcmp(event->name, "power_frequency") == 0 |
| || strcmp(event->name, "cpu_frequency") == 0){ |
| |
| ret = pevent_get_field_val(NULL, event, "state", &rec, &val, 0); |
| if (ret < 0) { |
| fprintf(stderr, _("power or cpu_frequecny event returned no state?\n")); |
| exit(-1); |
| } |
| |
| cpu->change_freq(time, val); |
| } |
| |
| if (strcmp(event->name, "power_start")==0) |
| cpu->go_idle(time); |
| if (strcmp(event->name, "power_end")==0) |
| cpu->go_unidle(time); |
| |
| #if 0 |
| unsigned int i; |
| for (i = 0; i < system_level.children.size(); i++) |
| if (system_level.children[i]) |
| system_level.children[i]->validate(); |
| #endif |
| } |
| |
| void process_cpu_data(void) |
| { |
| unsigned int i; |
| system_level.reset_pstate_data(); |
| |
| perf_events->process(); |
| |
| for (i = 0; i < system_level.children.size(); i++) |
| if (system_level.children[i]) |
| system_level.children[i]->validate(); |
| |
| } |
| |
| void end_cpu_data(void) |
| { |
| system_level.reset_pstate_data(); |
| |
| perf_events->clear(); |
| } |
| |
| void clear_cpu_data(void) |
| { |
| if (perf_events) |
| perf_events->release(); |
| delete perf_events; |
| } |
| |
| |
| void clear_all_cpus(void) |
| { |
| unsigned int i; |
| for (i = 0; i < all_cpus.size(); i++) { |
| delete all_cpus[i]; |
| } |
| all_cpus.clear(); |
| } |