As powertop is run now, it's a little tricky to get the list of
offending apps recorded for posterity or reporting.
This patch adds support for dumping the displayed data to stdout,
instead of into a ncurses window. It's not the cleanest thing in
the world, but it works. Required some minor tweaks to the display
routines (mostly adding some newlines).
Other things introduced in the process:
- getopt handling so you can specify this
- add an option to change the reporting period
Opinions? I'm still debating if this is the best mechanism
for what I'd like to do with it. (Basically, make it easy for users
to submit reports.)
Bill
diff -ru powertop-1.7/cpufreqstats.c powertop-1.7-new/cpufreqstats.c
--- powertop-1.7/cpufreqstats.c 2007-06-17 12:05:10.000000000 -0400
+++ powertop-1.7-new/cpufreqstats.c 2007-06-28 16:38:30.000000000 -0400
@@ -42,7 +42,7 @@
struct cpufreqdata delta[16];
-char cpufreqstrings[4][80];
+char cpufreqstrings[5][80];
int topfreq = -1;
static void zap(void)
@@ -98,6 +98,7 @@
memcpy(&oldfreqs, &freqs, sizeof(freqs));
memset(&cpufreqstrings, 0, sizeof(cpufreqstrings));
+ sprintf(cpufreqstrings[0], _("P-states (frequencies)\n"));
for (ret = 0; ret<16; ret++)
freqs[ret].count = 0;
@@ -164,8 +165,8 @@
qsort(&delta, maxfreq+1, sizeof(struct cpufreqdata), sort_by_freq);
topfreq = -1;
- for (ret =0 ; ret<=maxfreq; ret++) {
- sprintf(cpufreqstrings[ret], "%6s %5.1f%%",
HzToHuman(delta[ret].frequency), delta[ret].count * 100.0 / total_time);
+ for (ret = 0 ; ret<=maxfreq; ret++) {
+ sprintf(cpufreqstrings[ret+1], "%6s %5.1f%%\n",
HzToHuman(delta[ret].frequency), delta[ret].count * 100.0 / total_time);
if (delta[ret].count > total_time/2)
topfreq = ret;
}
diff -ru powertop-1.7/display.c powertop-1.7-new/display.c
--- powertop-1.7/display.c 2007-06-17 21:16:33.000000000 -0400
+++ powertop-1.7-new/display.c 2007-06-28 16:38:30.000000000 -0400
@@ -43,6 +43,7 @@
static WINDOW *suggestion_window;
static WINDOW *status_bar_window;
+#define print(win, y, x, fmt, args...) if (dump) printf(fmt, ## args); else
mvwprintw(win, y, x, fmt, ## args)
char status_bar_slots[10][40];
@@ -85,8 +86,8 @@
int maxx, maxy;
-int maxtimerstats;
-int maxwidth;
+int maxtimerstats = 50;
+int maxwidth = 200;
void setup_windows(void)
{
@@ -141,7 +142,7 @@
wbkgd(title_bar_window, COLOR_PAIR(PT_COLOR_HEADER_BAR));
werase(title_bar_window);
- mvwprintw(title_bar_window, 0, 0, " PowerTOP version 1.7 (C)
2007 Intel Corporation");
+ print(title_bar_window, 0, 0, " PowerTOP version 1.7 (C)
2007 Intel Corporation");
wrefresh(title_bar_window);
@@ -152,7 +153,7 @@
if (strlen(status_bar_slots[i])==0)
continue;
wattron(status_bar_window, A_REVERSE);
- mvwprintw(status_bar_window, 0, x, status_bar_slots[i]);
+ print(status_bar_window, 0, x, status_bar_slots[i]);
wattroff(status_bar_window, A_REVERSE);
x+= strlen(status_bar_slots[i])+1;
}
@@ -169,15 +170,15 @@
wattron(cstate_window, A_BOLD);
else
wattroff(cstate_window, A_BOLD);
- mvwprintw(cstate_window, i, 0, "%s", cstate_lines[i]);
+ print(cstate_window, i, 0, "%s", cstate_lines[i]);
}
- for (i=0; i<4; i++) {
+ for (i=0; i<5; i++) {
if (i == topfreq)
wattron(cstate_window, A_BOLD);
else
wattroff(cstate_window, A_BOLD);
- mvwprintw(cstate_window, i+2, 38, "%s", cpufreqstrings[i]);
+ print(cstate_window, i, 38, "%s", cpufreqstrings[i]);
}
wrefresh(cstate_window);
@@ -202,7 +203,7 @@
else if (ti>120 && capdelta > 0.001)
sprintf(buffer, _("Power usage (5 minute ACPI estimate) : %5.1f
W (%3.1f hours left)"), 3600*capdelta / ti, cap / (3600*capdelta/ti+0.01));
- mvwprintw(acpi_power_window, 0, 0, buffer);
+ print(acpi_power_window, 0, 0, "%s\n", buffer);
wrefresh(acpi_power_window);
}
@@ -217,7 +218,7 @@
wbkgd(wakeup_window, COLOR_PAIR(PT_COLOR_GREEN));
wattron(wakeup_window, A_BOLD);
- mvwprintw(wakeup_window, 0, 0, _("Wakeups-from-idle per second :
%4.1f"), d);
+ print(wakeup_window, 0, 0, _("Wakeups-from-idle per second : %4.1f\n"),
d);
wrefresh(wakeup_window);
}
@@ -228,25 +229,25 @@
if (!nostats) {
int counter = 0;
- mvwprintw(timerstat_window, 0, 0, _("Top causes for wakeups:"));
+ print(timerstat_window, 0, 0, _("Top causes for wakeups:\n"));
for (i = 0; i < linehead; i++)
if (lines[i].count > 0 && counter++ < maxtimerstats) {
if ((lines[i].count * 1.0 / ticktime) >= 10.0)
wattron(timerstat_window, A_BOLD);
else
wattroff(timerstat_window, A_BOLD);
- mvwprintw(timerstat_window, i+1, 0," %5.1f%%
(%5.1f) %s ", lines[i].count * 100.0 / linectotal,
+ print(timerstat_window, i+1, 0," %5.1f%%
(%5.1f) %s \n", lines[i].count * 100.0 / linectotal,
lines[i].count * 1.0 /
ticktime,
lines[i].string);
}
} else {
if (getuid() == 0) {
- mvwprintw(timerstat_window, 0, 0, _("No detailed
statistics available; please enable the CONFIG_TIMER_STATS kernel option\n"));
- mvwprintw(timerstat_window, 1, 0, _("This option is
located in the Kernel Debugging section of menuconfig\n"));
- mvwprintw(timerstat_window, 2, 0, _("(which is
CONFIG_DEBUG_KERNEL=y in the config file)\n"));
- mvwprintw(timerstat_window, 3, 0, _("Note: this is only
available in 2.6.21 and later kernels\n"));
+ print(timerstat_window, 0, 0, _("No detailed statistics
available; please enable the CONFIG_TIMER_STATS kernel option\n"));
+ print(timerstat_window, 1, 0, _("This option is located
in the Kernel Debugging section of menuconfig\n"));
+ print(timerstat_window, 2, 0, _("(which is
CONFIG_DEBUG_KERNEL=y in the config file)\n"));
+ print(timerstat_window, 3, 0, _("Note: this is only
available in 2.6.21 and later kernels\n"));
} else
- mvwprintw(timerstat_window, 0, 0, _("No detailed
statistics available; PowerTOP needs root privileges for that\n"));
+ print(timerstat_window, 0, 0, _("No detailed statistics
available; PowerTOP needs root privileges for that\n"));
}
@@ -256,6 +257,6 @@
void show_suggestion(char *sug)
{
werase(suggestion_window);
- mvwprintw(suggestion_window, 0, 0, "%s", sug);
+ print(suggestion_window, 0, 0, "%s", sug);
wrefresh(suggestion_window);
}
diff -ru powertop-1.7/powertop.c powertop-1.7-new/powertop.c
--- powertop-1.7/powertop.c 2007-06-17 21:16:31.000000000 -0400
+++ powertop-1.7-new/powertop.c 2007-06-28 16:44:19.000000000 -0400
@@ -22,6 +22,7 @@
* Arjan van de Ven <[EMAIL PROTECTED]>
*/
+#include <getopt.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -48,6 +49,8 @@
static int maxcstate = 0;
int topcstate = 0;
+int dump = 0;
+
#define IRQCOUNT 100
struct irqdata {
@@ -372,6 +375,15 @@
char cstate_lines[6][200];
+void usage()
+{
+ printf(_("Usage: powertop [OPTION...]\n"));
+ printf(_(" -d, --dump read wakeups once and print list of
top offenders\n"));
+ printf(_(" -t, --time=DOUBLE default time to gather data in
seconds\n"));
+ printf(_(" -h, --help Show this help message\n"));
+ exit(0);
+}
+
int main(int argc, char **argv)
{
char line[1024];
@@ -380,14 +392,41 @@
uint64_t cur_usage[8], cur_duration[8];
double wakeups_per_second = 0;
- read_data(&start_usage[0], &start_duration[0]);
-
- system("modprobe cpufreq_stats &> /dev/null");
-
setlocale (LC_ALL, "");
bindtextdomain ("powertop", "/usr/share/locale");
textdomain ("powertop");
+ while (1) {
+ static struct option opts[] = {
+ { "dump", 0, NULL, 'd' },
+ { "time", 1, NULL, 't' },
+ { "help", 0, NULL, 'h' },
+ { 0, 0, NULL, 0 }
+ };
+ int index = 0, c;
+
+ c = getopt_long(argc, argv, "dt:h", opts, &index);
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'd':
+ dump = 1;
+ break;
+ case 't':
+ ticktime = strtod(optarg, NULL);
+ break;
+ case 'h':
+ usage();
+ break;
+ default:
+ printf("getopt returned %d\n", c);
+ }
+ }
+
+ system("modprobe cpufreq_stats &> /dev/null");
+
+ read_data(&start_usage[0], &start_duration[0]);
+
memcpy(last_usage, start_usage, sizeof(last_usage));
memcpy(last_duration, start_duration, sizeof(last_duration));
@@ -441,12 +480,14 @@
totalevents += cur_usage[i] - last_usage[i];
}
- if (!ncursesinited) {
+ if (!ncursesinited && !dump) {
initialize_curses();
ncursesinited++;
}
- setup_windows();
- show_title_bar();
+ if (!dump) {
+ setup_windows();
+ show_title_bar();
+ }
memset(&cstate_lines, 0, sizeof(cstate_lines));
topcstate = -4;
@@ -459,7 +500,7 @@
c0 = sysconf(_SC_NPROCESSORS_ONLN) * ticktime * 1000 *
FREQ - totalticks;
if (c0 < 0)
c0 = 0; /* rounding errors in measurement might
make c0 go slightly negative.. this is confusing */
- sprintf(cstate_lines[0], _("Cn\t Avg residency
(%is)\t\tP-states (frequencies)\n"), (int)ticktime);
+ sprintf(cstate_lines[0], _("Cn\t Avg residency
(%is)\n"), (int)ticktime);
sprintf(cstate_lines[1], _("C0 (cpu running)
(%4.1f%%)\n"), c0 * 100.0 / (sysconf(_SC_NPROCESSORS_ONLN) * ticktime * 1000 *
FREQ));
for (i = 0; i < 4; i++)
if (cur_usage[i]) {
@@ -594,7 +635,8 @@
if (wakeups_per_second < 0)
ticktime = 2;
-
+ if (dump)
+ exit(EXIT_SUCCESS);
reset_suggestions();
suggest_kernel_config("CONFIG_USB_SUSPEND", 1,
Only in powertop-1.7-new: powertop.c~
diff -ru powertop-1.7/powertop.h powertop-1.7-new/powertop.h
--- powertop-1.7/powertop.h 2007-06-17 02:21:37.000000000 -0400
+++ powertop-1.7-new/powertop.h 2007-06-28 16:38:30.000000000 -0400
@@ -59,10 +59,11 @@
extern char cstate_lines[6][200];
-extern char cpufreqstrings[4][80];
+extern char cpufreqstrings[5][80];
extern int topcstate;
extern int topfreq;
+extern int dump;
extern char status_bar_slots[10][40];
extern char suggestion_key;
_______________________________________________
Power mailing list
[email protected]
http://www.bughost.org/mailman/listinfo/power