This patch gets the available C-states from cpuidle framework (sysfs) and gets the P-states information from the cpufreq (again, from sysfs). Thus it removes the hardcoded values for c and p states, and makes it generic enough to run on all the systems which plugin to cpuidle and cpufreq kernel framework.
Signed-off-by: Amit Arora amit.arora@linaro.org --- Makefile | 2 +- cpufreqstats.c | 3 +- display.c | 15 ++++++--- generic_cstates.c | 63 ++++++++++++++++++++++++++++++++++++++++ omapcstates.c | 64 ----------------------------------------- powertop.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++----- powertop.h | 23 +++----------- 7 files changed, 154 insertions(+), 98 deletions(-) create mode 100644 generic_cstates.c delete mode 100644 omapcstates.c
diff --git a/Makefile b/Makefile index 0b41dc4..d9e4883 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ CC?=gcc
OBJS = powertop.o config.o process.o misctips.o bluetooth.o display.o suggestions.o wireless.o cpufreq.o \ sata.o xrandr.o ethernet.o cpufreqstats.o usb.o urbnum.o intelcstates.o wifi-new.o perf.o \ - alsa-power.o ahci-alpm.o dmesg.o devicepm.o omapcstates.o + alsa-power.o ahci-alpm.o dmesg.o devicepm.o generic_cstates.o
powertop: $(OBJS) Makefile powertop.h diff --git a/cpufreqstats.c b/cpufreqstats.c index b250407..6cd36ee 100644 --- a/cpufreqstats.c +++ b/cpufreqstats.c @@ -42,7 +42,7 @@ struct cpufreqdata oldfreqs[16];
struct cpufreqdata delta[16];
-char cpufreqstrings[MAX_NUM_PSTATES+1][80]; +char **cpufreqstrings; int topfreq = -1;
static void zap(void) @@ -111,7 +111,6 @@ void do_cpufreq_stats(void) uint64_t total_time = 0;
memcpy(&oldfreqs, &freqs, sizeof(freqs)); - memset(&cpufreqstrings, 0, sizeof(cpufreqstrings)); sprintf(cpufreqstrings[0], _("P-states (frequencies)\n"));
for (ret = 0; ret<16; ret++) diff --git a/display.c b/display.c index cc81efe..de9146b 100644 --- a/display.c +++ b/display.c @@ -91,7 +91,12 @@ int maxwidth = 200;
void setup_windows(void) { - int yline = MAX_NUM_CSTATES; + int yline; + + if (max_num_cstates > max_num_pstates) + yline = max_num_cstates; + else + yline = max_num_pstates;
getmaxyx(stdscr, maxy, maxx);
@@ -152,7 +157,7 @@ void show_title_bar(void) werase(status_bar_window);
x = 0; - for (i=0; i < MAX_CSTATE_LINES; i++) { + for (i=0; i < max_cstate_lines; i++) { if (strlen(status_bar_slots[i])==0) continue; wattron(status_bar_window, A_REVERSE); @@ -168,18 +173,18 @@ void show_cstates(void) int i, count = 0; werase(cstate_window);
- for (i=0; i < MAX_CSTATE_LINES; i++) { + for (i=0; i < max_cstate_lines; i++) { if (i == topcstate+1) wattron(cstate_window, A_BOLD); else wattroff(cstate_window, A_BOLD); - if (strlen(cstate_lines[i]) && count <= MAX_CSTATE_LINES) { + if (strlen(cstate_lines[i]) && count <= max_cstate_lines) { print(cstate_window, count, 0, "%s", cstate_lines[i]); count++; } }
- for (i=0; i <= MAX_NUM_PSTATES; i++) { + for (i=0; i <= max_num_pstates; i++) { if (i == topfreq+1) wattron(cstate_window, A_BOLD); else diff --git a/generic_cstates.c b/generic_cstates.c new file mode 100644 index 0000000..dbee3c1 --- /dev/null +++ b/generic_cstates.c @@ -0,0 +1,63 @@ +/* + * Copyright 2008, Texas Instruments Incorporated. + * Copyright 2010, IBM Corporation + * + * This file prints the C states supported by any processor. + * (Based on intelcstates.c) + * + * 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 + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <sys/types.h> +#include <dirent.h> +#include <ctype.h> + +#include "powertop.h" + + +/** + * print_generic_cstates() - Prints the list of supported C-states. + * + * This functions uses standard sysfs interface of the cpuidle framework + * to extract the information of the C-states supported by the Linux + * kernel. + **/ +void print_generic_cstates(void) +{ + DIR *dir; + struct dirent *entry; + + dir = opendir("/sys/devices/system/cpu/cpu0/cpuidle"); + + if (dir) { + printf(_("Supported C-states : ")); + + while ((entry = readdir(dir))) { + if (strlen(entry->d_name) < 3) + continue; + + printf("C%s ", entry->d_name); + } + printf("\n"); + + closedir(dir); + } +} diff --git a/omapcstates.c b/omapcstates.c deleted file mode 100644 index 9d1da4f..0000000 --- a/omapcstates.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2008, Texas Instruments Incorporated. - * - * This file prints the C states supported by the OMAP processor. - * (Based on intelcstates.c) - * - * 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 - */ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <sys/types.h> -#include <dirent.h> -#include <ctype.h> - -#include "powertop.h" - - -#if defined(OMAP3) -/** - * print_omap3_cstates() - Prints the list of supported C-states. - * - * This functions uses standard sysfs interface of the cpuidle framework - * to extract the information of the C-states supported by the Linux - * kernel. - **/ -void print_omap3_cstates(void) -{ - DIR *dir; - struct dirent *entry; - - dir = opendir("/sys/devices/system/cpu/cpu0/cpuidle"); - - if (dir) { - printf(_("Supported C-states : ")); - - while ((entry = readdir(dir))) { - if (strlen(entry->d_name) < 3) - continue; - - printf("C%s ", entry->d_name); - } - printf("\n"); - - closedir(dir); - } -} -#endif diff --git a/powertop.c b/powertop.c index 7a32623..6fd3efe 100644 --- a/powertop.c +++ b/powertop.c @@ -40,6 +40,7 @@
#include "powertop.h"
+extern void print_generic_cstates(void);
uint64_t start_usage[8], start_duration[8]; uint64_t last_usage[8], last_duration[8]; @@ -85,6 +86,70 @@ time_t prev_bat_time = 0;
double displaytime = 0.0;
+char **cstate_lines; + +void init_numstates(void) +{ + DIR *dir; + FILE *fp; + struct dirent *entry; + int i, count = 0; + char line[1024]; + + dir = opendir("/sys/devices/system/cpu/cpu0/cpuidle"); + if (dir) { + while ((entry = readdir(dir))) { + if (strlen(entry->d_name) < 3) + continue; + count++; + } + closedir(dir); + } + max_num_cstates = count; + count = 0; + + fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", + "r"); + if (fp) { + while (fgets(line, sizeof(line), fp)!=NULL) + count++; + fclose(fp); + } + max_num_pstates = count; + + if (max_num_cstates > max_num_pstates) + max_cstate_lines = max_num_cstates + 3; + else + max_cstate_lines = max_num_pstates + 3; + + /* Now, allocate memory */ + + cpufreqstrings = (char **)calloc((max_num_pstates+1), sizeof(char *)); + assert(cpufreqstrings!=0); + for (i=0; i<max_num_pstates+1; i++) { + cpufreqstrings[i] = (char *)calloc(80, sizeof(char)); + assert(cpufreqstrings[i]!=0); + } + + cstate_lines = (char **)calloc(max_cstate_lines, sizeof(char *)); + assert(cstate_lines!=0); + for (i=0; i<max_cstate_lines; i++) { + cstate_lines[i] = (char *)calloc(200, sizeof(char)); + assert(cstate_lines[i]!=0); + } + +} + +void free_numstates(void) +{ + int i; + + for (i=0; i<max_num_pstates+1; i++) + free(cpufreqstrings[i]); + free(cpufreqstrings); + cpufreqstrings = NULL; +} + void push_line(char *string, int count) { int i; @@ -824,8 +889,6 @@ void print_battery_sysfs(void) show_acpi_power_line(rate, cap, prev_bat_cap - cap, time(NULL) - prev_bat_time); }
-char cstate_lines[MAX_CSTATE_LINES][200]; - void usage() { printf(_("Usage: powertop [OPTION...]\n")); @@ -902,6 +965,8 @@ int main(int argc, char **argv) memcpy(last_usage, start_usage, sizeof(last_usage)); memcpy(last_duration, start_duration, sizeof(last_duration));
+ init_numstates(); + do_proc_irq(); do_proc_irq(); do_cpufreq_stats(); @@ -924,8 +989,8 @@ int main(int argc, char **argv) printf("\n\n"); #if defined (__I386__) print_intel_cstates(); -#elif defined (OMAP3) - print_omap3_cstates(); +#else + print_generic_cstates(); #endif stop_timerstats();
@@ -963,7 +1028,7 @@ int main(int argc, char **argv)
totalticks = 0; totalevents = 0; - for (i = 0; i < MAX_NUM_CSTATES; i++) + for (i = 0; i < max_num_cstates; i++) if (cur_usage[i]) { totalticks += cur_duration[i] - last_duration[i]; totalevents += cur_usage[i] - last_usage[i]; @@ -978,8 +1043,7 @@ int main(int argc, char **argv) show_title_bar(); }
- memset(&cstate_lines, 0, sizeof(cstate_lines)); - topcstate = -(MAX_NUM_CSTATES); + topcstate = -(max_num_cstates); if (totalevents == 0 && maxcstate <= 1) { sprintf(cstate_lines[5],_("< Detailed C-state information is not available.>\n")); } else { @@ -993,7 +1057,7 @@ int main(int argc, char **argv) sprintf(cstate_lines[1], _("C0 (cpu running) (%4.1f%%)\n"), percentage); if (percentage > 50) topcstate = 0; - for (i = 0; i < MAX_NUM_CSTATES; i++) + for (i = 0; i < max_num_cstates; i++) if (cur_usage[i]) { sleept = (cur_duration[i] - last_duration[i]) / (cur_usage[i] - last_usage[i] + 0.1) / FREQ; @@ -1300,5 +1364,7 @@ int main(int argc, char **argv) }
end_data_dirty_capture(); + + free_numstates(); return 0; } diff --git a/powertop.h b/powertop.h index 21f5538..4017cfe 100644 --- a/powertop.h +++ b/powertop.h @@ -30,19 +30,9 @@
#define VERSION "1.12"
-#if defined(__i386__) -#define MAX_NUM_CSTATES 4 -#define MAX_NUM_PSTATES 5 - -#elif defined(OMAP3) -#define MAX_NUM_CSTATES 7 -#define MAX_NUM_PSTATES 5 - -#else -#error "No valid architecture is defined." -#endif - -#define MAX_CSTATE_LINES (MAX_NUM_CSTATES + 3) +int max_num_cstates; +int max_num_pstates; +int max_cstate_lines;
struct line { char *string; @@ -83,11 +73,8 @@ void usb_activity_hint(void); void devicepm_activity_hint(void);
- - - -extern char cstate_lines[MAX_CSTATE_LINES][200]; -extern char cpufreqstrings[MAX_NUM_PSTATES+1][80]; +extern char **cpufreqstrings; +extern char **cstate_lines;
extern int topcstate; extern int topfreq;
On 10 Jul 29, Amit Arora wrote:
This patch gets the available C-states from cpuidle framework (sysfs) and gets the P-states information from the cpufreq (again, from sysfs). Thus it removes the hardcoded values for c and p states, and makes it generic enough to run on all the systems which plugin to cpuidle and cpufreq kernel framework.
Signed-off-by: Amit Arora amit.arora@linaro.org
Makefile | 2 +- cpufreqstats.c | 3 +- display.c | 15 ++++++--- generic_cstates.c | 63 ++++++++++++++++++++++++++++++++++++++++ omapcstates.c | 64 ----------------------------------------- powertop.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++----- powertop.h | 23 +++----------- 7 files changed, 154 insertions(+), 98 deletions(-) create mode 100644 generic_cstates.c delete mode 100644 omapcstates.c
diff --git a/Makefile b/Makefile index 0b41dc4..d9e4883 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ CC?=gcc OBJS = powertop.o config.o process.o misctips.o bluetooth.o display.o suggestions.o wireless.o cpufreq.o \ sata.o xrandr.o ethernet.o cpufreqstats.o usb.o urbnum.o intelcstates.o wifi-new.o perf.o \
- alsa-power.o ahci-alpm.o dmesg.o devicepm.o omapcstates.o
- alsa-power.o ahci-alpm.o dmesg.o devicepm.o generic_cstates.o
powertop: $(OBJS) Makefile powertop.h diff --git a/cpufreqstats.c b/cpufreqstats.c index b250407..6cd36ee 100644 --- a/cpufreqstats.c +++ b/cpufreqstats.c @@ -42,7 +42,7 @@ struct cpufreqdata oldfreqs[16]; struct cpufreqdata delta[16]; -char cpufreqstrings[MAX_NUM_PSTATES+1][80]; +char **cpufreqstrings; int topfreq = -1; static void zap(void) @@ -111,7 +111,6 @@ void do_cpufreq_stats(void) uint64_t total_time = 0; memcpy(&oldfreqs, &freqs, sizeof(freqs));
- memset(&cpufreqstrings, 0, sizeof(cpufreqstrings)); sprintf(cpufreqstrings[0], _("P-states (frequencies)\n"));
for (ret = 0; ret<16; ret++) diff --git a/display.c b/display.c index cc81efe..de9146b 100644 --- a/display.c +++ b/display.c @@ -91,7 +91,12 @@ int maxwidth = 200; void setup_windows(void) {
- int yline = MAX_NUM_CSTATES;
- int yline;
- if (max_num_cstates > max_num_pstates)
yline = max_num_cstates;
- else
yline = max_num_pstates;
getmaxyx(stdscr, maxy, maxx); @@ -152,7 +157,7 @@ void show_title_bar(void) werase(status_bar_window); x = 0;
- for (i=0; i < MAX_CSTATE_LINES; i++) {
- for (i=0; i < max_cstate_lines; i++) { if (strlen(status_bar_slots[i])==0) continue; wattron(status_bar_window, A_REVERSE);
@@ -168,18 +173,18 @@ void show_cstates(void) int i, count = 0; werase(cstate_window);
- for (i=0; i < MAX_CSTATE_LINES; i++) {
- for (i=0; i < max_cstate_lines; i++) { if (i == topcstate+1) wattron(cstate_window, A_BOLD); else wattroff(cstate_window, A_BOLD);
if (strlen(cstate_lines[i]) && count <= MAX_CSTATE_LINES) {
} }if (strlen(cstate_lines[i]) && count <= max_cstate_lines) { print(cstate_window, count, 0, "%s", cstate_lines[i]); count++;
- for (i=0; i <= MAX_NUM_PSTATES; i++) {
- for (i=0; i <= max_num_pstates; i++) { if (i == topfreq+1) wattron(cstate_window, A_BOLD); else
diff --git a/generic_cstates.c b/generic_cstates.c new file mode 100644 index 0000000..dbee3c1 --- /dev/null +++ b/generic_cstates.c @@ -0,0 +1,63 @@ +/*
- Copyright 2008, Texas Instruments Incorporated.
- Copyright 2010, IBM Corporation
- This file prints the C states supported by any processor.
- (Based on intelcstates.c)
- 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
- */
+#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <sys/types.h> +#include <dirent.h> +#include <ctype.h>
+#include "powertop.h"
+/**
- print_generic_cstates() - Prints the list of supported C-states.
- This functions uses standard sysfs interface of the cpuidle framework
- to extract the information of the C-states supported by the Linux
- kernel.
- **/
+void print_generic_cstates(void) +{
- DIR *dir;
- struct dirent *entry;
- dir = opendir("/sys/devices/system/cpu/cpu0/cpuidle");
Is this safe for multi-core cases? Is it safe to assume that the c-states on all cores will be the same?
Also, I see that powertop shows "Avg. residency" in each C-state. Is that an average of the the residency of each core in a particular C-state?
- if (dir) {
printf(_("Supported C-states : "));
while ((entry = readdir(dir))) {
if (strlen(entry->d_name) < 3)
continue;
printf("C%s ", entry->d_name);
}
printf("\n");
closedir(dir);
- }
+} diff --git a/omapcstates.c b/omapcstates.c deleted file mode 100644 index 9d1da4f..0000000 --- a/omapcstates.c +++ /dev/null @@ -1,64 +0,0 @@ -/*
- Copyright 2008, Texas Instruments Incorporated.
- This file prints the C states supported by the OMAP processor.
- (Based on intelcstates.c)
- 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
- */
-#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <sys/types.h> -#include <dirent.h> -#include <ctype.h>
-#include "powertop.h"
-#if defined(OMAP3) -/**
- print_omap3_cstates() - Prints the list of supported C-states.
- This functions uses standard sysfs interface of the cpuidle framework
- to extract the information of the C-states supported by the Linux
- kernel.
- **/
-void print_omap3_cstates(void) -{
- DIR *dir;
- struct dirent *entry;
- dir = opendir("/sys/devices/system/cpu/cpu0/cpuidle");
- if (dir) {
printf(_("Supported C-states : "));
while ((entry = readdir(dir))) {
if (strlen(entry->d_name) < 3)
continue;
printf("C%s ", entry->d_name);
}
printf("\n");
closedir(dir);
- }
-} -#endif diff --git a/powertop.c b/powertop.c index 7a32623..6fd3efe 100644 --- a/powertop.c +++ b/powertop.c @@ -40,6 +40,7 @@ #include "powertop.h" +extern void print_generic_cstates(void); uint64_t start_usage[8], start_duration[8]; uint64_t last_usage[8], last_duration[8]; @@ -85,6 +86,70 @@ time_t prev_bat_time = 0; double displaytime = 0.0; +char **cstate_lines;
+void init_numstates(void) +{
- DIR *dir;
- FILE *fp;
- struct dirent *entry;
- int i, count = 0;
- char line[1024];
- dir = opendir("/sys/devices/system/cpu/cpu0/cpuidle");
Ditto.
- if (dir) {
while ((entry = readdir(dir))) {
if (strlen(entry->d_name) < 3)
continue;
count++;
}
closedir(dir);
- }
- max_num_cstates = count;
- count = 0;
- fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state",
"r");
- if (fp) {
while (fgets(line, sizeof(line), fp)!=NULL)
count++;
fclose(fp);
- }
- max_num_pstates = count;
- if (max_num_cstates > max_num_pstates)
max_cstate_lines = max_num_cstates + 3;
- else
max_cstate_lines = max_num_pstates + 3;
- /* Now, allocate memory */
- cpufreqstrings = (char **)calloc((max_num_pstates+1), sizeof(char *));
- assert(cpufreqstrings!=0);
- for (i=0; i<max_num_pstates+1; i++) {
cpufreqstrings[i] = (char *)calloc(80, sizeof(char));
assert(cpufreqstrings[i]!=0);
- }
- cstate_lines = (char **)calloc(max_cstate_lines, sizeof(char *));
- assert(cstate_lines!=0);
- for (i=0; i<max_cstate_lines; i++) {
cstate_lines[i] = (char *)calloc(200, sizeof(char));
assert(cstate_lines[i]!=0);
- }
+}
+void free_numstates(void) +{
- int i;
- for (i=0; i<max_num_pstates+1; i++)
free(cpufreqstrings[i]);
- free(cpufreqstrings);
- cpufreqstrings = NULL;
+}
void push_line(char *string, int count) { int i; @@ -824,8 +889,6 @@ void print_battery_sysfs(void) show_acpi_power_line(rate, cap, prev_bat_cap - cap, time(NULL) - prev_bat_time); } -char cstate_lines[MAX_CSTATE_LINES][200];
void usage() { printf(_("Usage: powertop [OPTION...]\n")); @@ -902,6 +965,8 @@ int main(int argc, char **argv) memcpy(last_usage, start_usage, sizeof(last_usage)); memcpy(last_duration, start_duration, sizeof(last_duration));
- init_numstates();
- do_proc_irq(); do_proc_irq(); do_cpufreq_stats();
@@ -924,8 +989,8 @@ int main(int argc, char **argv) printf("\n\n"); #if defined (__I386__) print_intel_cstates();
If we now have print_generic_cstates (below), then can't we get rid of the #ifdef'ery for I386 vs. others?
-#elif defined (OMAP3)
- print_omap3_cstates();
+#else
- print_generic_cstates();
#endif stop_timerstats(); @@ -963,7 +1028,7 @@ int main(int argc, char **argv) totalticks = 0; totalevents = 0;
for (i = 0; i < MAX_NUM_CSTATES; i++)
for (i = 0; i < max_num_cstates; i++) if (cur_usage[i]) { totalticks += cur_duration[i] - last_duration[i]; totalevents += cur_usage[i] - last_usage[i];
@@ -978,8 +1043,7 @@ int main(int argc, char **argv) show_title_bar(); }
memset(&cstate_lines, 0, sizeof(cstate_lines));
topcstate = -(MAX_NUM_CSTATES);
if (totalevents == 0 && maxcstate <= 1) { sprintf(cstate_lines[5],_("< Detailed C-state information is not available.>\n")); } else {topcstate = -(max_num_cstates);
@@ -993,7 +1057,7 @@ int main(int argc, char **argv) sprintf(cstate_lines[1], _("C0 (cpu running) (%4.1f%%)\n"), percentage); if (percentage > 50) topcstate = 0;
for (i = 0; i < MAX_NUM_CSTATES; i++)
for (i = 0; i < max_num_cstates; i++) if (cur_usage[i]) { sleept = (cur_duration[i] - last_duration[i]) / (cur_usage[i] - last_usage[i] + 0.1) / FREQ;
@@ -1300,5 +1364,7 @@ int main(int argc, char **argv) } end_data_dirty_capture();
- free_numstates(); return 0;
} diff --git a/powertop.h b/powertop.h index 21f5538..4017cfe 100644 --- a/powertop.h +++ b/powertop.h @@ -30,19 +30,9 @@ #define VERSION "1.12" -#if defined(__i386__) -#define MAX_NUM_CSTATES 4 -#define MAX_NUM_PSTATES 5
-#elif defined(OMAP3) -#define MAX_NUM_CSTATES 7 -#define MAX_NUM_PSTATES 5
-#else -#error "No valid architecture is defined." -#endif
-#define MAX_CSTATE_LINES (MAX_NUM_CSTATES + 3) +int max_num_cstates; +int max_num_pstates; +int max_cstate_lines; struct line { char *string; @@ -83,11 +73,8 @@ void usb_activity_hint(void); void devicepm_activity_hint(void);
-extern char cstate_lines[MAX_CSTATE_LINES][200]; -extern char cpufreqstrings[MAX_NUM_PSTATES+1][80]; +extern char **cpufreqstrings; +extern char **cstate_lines; extern int topcstate; extern int topfreq; -- 1.7.0.4
linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
On Thu, Jul 29, 2010 at 6:18 PM, Amit Kucheria amit.kucheria@linaro.org wrote:
On 10 Jul 29, Amit Arora wrote:
+/**
- print_generic_cstates() - Prints the list of supported C-states.
- This functions uses standard sysfs interface of the cpuidle framework
- to extract the information of the C-states supported by the Linux
- kernel.
- **/
+void print_generic_cstates(void) +{
- DIR *dir;
- struct dirent *entry;
- dir = opendir("/sys/devices/system/cpu/cpu0/cpuidle");
Is this safe for multi-core cases? Is it safe to assume that the c-states on all cores will be the same?
Am not sure about this. Are you aware of any case where different cores may have different number of supported c-states ?
BTW, this doesn't change the powertop output for c-states (Avg residency %, etc). For that we go through each core to find out supported cstates and related information (time, desc etc.).
But, yes, if we may have different c-states for different cpus/cores, it will make sense to go through each core to find out supported c-state levels.
Also, I see that powertop shows "Avg. residency" in each C-state. Is that an average of the the residency of each core in a particular C-state?
Yes. It is an average of all the cores. read_data_cpuidle() walks through all the cpuN directories under /sys/devices/system/cpu/ and collates this information from each core for a particular c-state level. And main() (which calls read_data_cpuidle via read_data) in the while loop, takes an average of the time duration for each state depending on number of online CPUs.
do_proc_irq(); do_proc_irq(); do_cpufreq_stats(); @@ -924,8 +989,8 @@ int main(int argc, char **argv) printf("\n\n"); #if defined (__I386__) print_intel_cstates();
If we now have print_generic_cstates (below), then can't we get rid of the #ifdef'ery for I386 vs. others?
i386 does some extra work in finding out which states are supported by the CPU (from cpuidle sysfs interface) and which ones are supported by BIOS (it uses x86 cpuid() call for this).
So, even if we keep common function for all archs, we will need "#ifdef __i386__" inside that function.
Thanks for looking at the patches! -- Regards, Amit Arora