Discussion:
[PATCH 1/10] add on-demand window refresh
Sergey Senozhatsky
2012-04-24 20:33:50 UTC
Permalink
Introduce support for on-demand window refresh (tab).
Extended tab_window class now defines virtual window_refresh() function,
which should be implemented in derived classes according to refresh
logic.

Add support for window refresh to tuninig tab. For example, this
allows to update list with plugged-in/unplagged USB devices, etc., w/o
the need of powertop restart.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
display.cpp | 15 +++++++++++++++
display.h | 2 ++
main.cpp | 3 ++-
tuning/tuning.cpp | 28 ++++++++++++++++++++--------
4 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/display.cpp b/display.cpp
index 150834a..8979c98 100644
--- a/display.cpp
+++ b/display.cpp
@@ -259,6 +259,7 @@ void cursor_up(void)

show_cur_tab();
}
+
void cursor_enter(void)
{
class tab_window *w;
@@ -272,6 +273,20 @@ void cursor_enter(void)
show_cur_tab();
}

+void window_refresh()
+{
+ class tab_window *w;
+
+ w = tab_windows[tab_names[current_tab]];
+
+ if (w) {
+ w->window_refresh();
+ w->repaint();
+ }
+
+ show_cur_tab();
+}
+
int ncurses_initialized(void)
{
if (display)
diff --git a/display.h b/display.h
index c4f946c..78d1735 100644
--- a/display.h
+++ b/display.h
@@ -42,6 +42,7 @@ extern void show_cur_tab(void);
extern void cursor_up(void);
extern void cursor_down(void);
extern void cursor_enter(void);
+extern void window_refresh(void);

#ifndef DISABLE_NCURSES
class tab_window {
@@ -54,6 +55,7 @@ public:
virtual void cursor_up(void) { if (cursor_pos > 0) cursor_pos--; repaint(); };

virtual void cursor_enter(void) { };
+ virtual void window_refresh() { };

virtual void repaint(void) { };
virtual void expose(void) { cursor_pos = 0; repaint();};
diff --git a/main.cpp b/main.cpp
index 67db2eb..afc124b 100644
--- a/main.cpp
+++ b/main.cpp
@@ -136,7 +136,8 @@ static void do_sleep(int seconds)
case 10:
cursor_enter();
break;
- case 'i':
+ case 'r':
+ window_refresh();
return;
case KEY_EXIT:
case 'q':
diff --git a/tuning/tuning.cpp b/tuning/tuning.cpp
index 8930365..1ca33d7 100644
--- a/tuning/tuning.cpp
+++ b/tuning/tuning.cpp
@@ -50,17 +50,12 @@ public:
virtual void repaint(void);
virtual void cursor_enter(void);
virtual void expose(void);
+ virtual void window_refresh(void);
};
#endif // DISABLE_NCURSES
-void initialize_tuning(void)
-{
-#ifndef DISABLE_NCURSES
- class tuning_window *w;
-
- w = new tuning_window();
- create_tab("Tunables", _("Tunables"), w, _(" <ESC> Exit | <Enter> Toggle tunable"));
-#endif // DISABLE_NCURSES

+static void init_tuning(void)
+{
add_sysfs_tunable(_("Enable Audio codec power management"), "/sys/module/snd_hda_intel/parameters/power_save", "1");
add_sysfs_tunable(_("Enable SATA link power management for /dev/sda"), "/sys/class/scsi_host/host0/link_power_management_policy", "min_power");
add_sysfs_tunable(_("NMI watchdog should be turned off"), "/proc/sys/kernel/nmi_watchdog", "0");
@@ -75,6 +70,18 @@ void initialize_tuning(void)
add_cpufreq_tunable();

sort_tunables();
+}
+
+void initialize_tuning(void)
+{
+#ifndef DISABLE_NCURSES
+ class tuning_window *w;
+
+ w = new tuning_window();
+ create_tab("Tunables", _("Tunables"), w, _(" <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh"));
+#endif // DISABLE_NCURSES
+
+ init_tuning();

#ifndef DISABLE_NCURSES
w->cursor_max = all_tunables.size() - 1;
@@ -172,6 +179,11 @@ static bool tunables_sort(class tunable * i, class tunable * j)
return false;
}

+void tuning_window::window_refresh()
+{
+ clear_tuning();
+ init_tuning();
+}

static void sort_tunables(void)
{
Sergey Senozhatsky
2012-04-24 20:36:50 UTC
Permalink
No need to call werase() each time cursor changes its position. In fact the only
time we should call it - is when list of tunables changed.
Introduce static bool flag to mark the need of werase() call.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
tuning/tuning.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tuning/tuning.cpp b/tuning/tuning.cpp
index 1ca33d7..57ef3d1 100644
--- a/tuning/tuning.cpp
+++ b/tuning/tuning.cpp
@@ -43,6 +43,7 @@
#include "../lib.h"

static void sort_tunables(void);
+static bool should_clear = FALSE;

#ifndef DISABLE_NCURSES
class tuning_window: public tab_window {
@@ -96,13 +97,15 @@ static void __tuning_update_display(int cursor_pos)
WINDOW *win;
unsigned int i;

-
win = get_ncurses_win("Tunables");

if (!win)
return;

- wclear(win);
+ if (should_clear) {
+ should_clear = FALSE;
+ wclear(win);
+ }

wmove(win, 2,0);

@@ -182,6 +185,7 @@ static bool tunables_sort(class tunable * i, class tunable * j)
void tuning_window::window_refresh()
{
clear_tuning();
+ should_clear = TRUE;
init_tuning();
}
Sergey Senozhatsky
2012-04-24 20:38:24 UTC
Permalink
Introduce library routine get_user_input(char *buf, unsigned sz),
which is used to obtain user input.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
lib.cpp | 13 +++++++++++++
lib.h | 1 +
2 files changed, 14 insertions(+)

diff --git a/lib.cpp b/lib.cpp
index 109c48e..53638dd 100644
--- a/lib.cpp
+++ b/lib.cpp
@@ -56,6 +56,7 @@ extern "C" {
#endif
#include <limits>
#include <math.h>
+#include <ncurses.h>

static int kallsyms_read = 0;

@@ -400,3 +401,15 @@ void process_directory(const char *d_name, callback fn)

closedir(dir);
}
+
+int get_user_input(char *buf, unsigned sz)
+{
+ fflush(stdout);
+ echo();
+ /* Upon successful completion, these functions return OK. Otherwise, they return ERR. */
+ int ret = getnstr(buf, sz);
+ noecho();
+ fflush(stdout);
+ /* to distinguish between getnstr error and empty line */
+ return ret || strlen(buf);
+}
diff --git a/lib.h b/lib.h
index 1282225..c345985 100644
--- a/lib.h
+++ b/lib.h
@@ -79,5 +79,6 @@ extern int equals(double a, double b);
typedef void (*callback)(const char*);
extern void process_directory(const char *d_name, callback fn);
extern int utf_ok;
+extern int get_user_input(char *buf, unsigned sz);

#endif
Sergey Senozhatsky
2012-04-24 20:41:13 UTC
Permalink
Introduce ability to set powertop refresh timeout via `-s` switch.
Currently, measurement timeout is allowed to be within [1,32] secs
range.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
main.cpp | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/main.cpp b/main.cpp
index afc124b..77e6d05 100644
--- a/main.cpp
+++ b/main.cpp
@@ -60,7 +60,7 @@
#define DEBUGFS_MAGIC 0x64626720

int debug_learning = 0;
-
+unsigned time_out = 20;
int leave_powertop = 0;

static const struct option long_options[] =
@@ -83,6 +83,20 @@ static void print_version()
printf(_("Powertop version" POWERTOP_VERSION ", compiled on "__DATE__ "\n"));
}

+static bool set_refresh_timeout()
+{
+ static char buf[4];
+ mvprintw(1, 0, "%s (currently %u): ", _("Set refresh time out"), time_out);
+ memset(buf, '\0', sizeof(buf));
+ get_user_input(buf, sizeof(buf) - 1);
+ show_tab(0);
+ unsigned time = strtoul(buf, NULL, 0);
+ if (!time) return 0;
+ if (time > 32) time = 32;
+ time_out = time;
+ return 1;
+}
+
static void print_usage()
{
printf(_("Usage: powertop [OPTIONS]\n\n"));
@@ -136,6 +150,10 @@ static void do_sleep(int seconds)
case 10:
cursor_enter();
break;
+ case 's':
+ if (set_refresh_timeout())
+ return;
+ break;
case 'r':
window_refresh();
return;
@@ -259,7 +277,6 @@ int main(int argc, char **argv)
int c;
bool wantreport = FALSE;
char filename[4096];;
- int timetotest = 20;
int iterations = 1;
struct statfs st_fs;

@@ -349,7 +366,7 @@ int main(int argc, char **argv)
break;

case 't':
- timetotest = (optarg ? atoi(optarg) : 20);
+ time_out = (optarg ? atoi(optarg) : 20);
break;

case 'i':
@@ -368,7 +385,7 @@ int main(int argc, char **argv)
}

if (wantreport)
- report(timetotest, iterations, filename);
+ report(time_out, iterations, filename);

if (debug_learning)
printf("Learning debugging enabled\n");
@@ -397,7 +414,7 @@ int main(int argc, char **argv)


while (!leave_powertop) {
- one_measurement(timetotest);
+ one_measurement(time_out);
show_cur_tab();
learn_parameters(15, 0);
}
Sergey Senozhatsky
2012-04-24 20:42:57 UTC
Permalink
Suppress `warning: suggest explicit braces to avoid ambiguous ‘else’ [-Wparentheses]'
compilation warning.

Signed-off-by: Sergey Senozhatsky <***@gmail.com>

---
tuning/tuning.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tuning/tuning.cpp b/tuning/tuning.cpp
index 57ef3d1..3fd89f3 100644
--- a/tuning/tuning.cpp
+++ b/tuning/tuning.cpp
@@ -286,11 +286,12 @@ void report_show_tunables(void)
fprintf(reportout.csv_report,"\"%s\", \n", all_untunables[i]->description());
}

- if (line > 0)
+ if (line > 0) {
if(reporttype)
fprintf(reportout.http_report,"</table>\n");
else
fprintf(reportout.csv_report,"\n");
+ }

line = 0;
for (i = 0; i < all_tunables.size(); i++) {
Sergey Senozhatsky
2012-04-24 20:44:34 UTC
Permalink
Suppress `warning: comparison between signed and unsigned integer expressions [-Wsign-compare]'
compilation warning.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
tuning/tuning.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tuning/tuning.cpp b/tuning/tuning.cpp
index 3fd89f3..e7722c1 100644
--- a/tuning/tuning.cpp
+++ b/tuning/tuning.cpp
@@ -332,12 +332,12 @@ void report_show_tunables(void)

void clear_tuning()
{
- for (int i = 0; i < all_tunables.size(); i++) {
+ for (size_t i = 0; i < all_tunables.size(); i++) {
delete all_tunables[i];
}
all_tunables.clear();

- for (int i = 0; i < all_untunables.size(); i++) {
+ for (size_t i = 0; i < all_untunables.size(); i++) {
delete all_untunables[i];
}
all_untunables.clear();
Sergey Senozhatsky
2012-04-24 20:46:33 UTC
Permalink
Add virtual .dtor to tab_window class.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
display.h | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/display.h b/display.h
index 78d1735..e0f66a3 100644
--- a/display.h
+++ b/display.h
@@ -60,6 +60,12 @@ public:
virtual void repaint(void) { };
virtual void expose(void) { cursor_pos = 0; repaint();};
virtual void hide(void) { };
+
+ virtual ~tab_window()
+ {
+ delwin(win);
+ win = NULL;
+ }
};

extern map<string, class tab_window *> tab_windows;
Sergey Senozhatsky
2012-04-24 20:49:47 UTC
Permalink
Rewrite is_deferred().
No need to check for !handler, since it's allocated member array.
"total events" substrig search is redundant -- EOF should do the
same. Also replace strchr() with "D," substring search.
Patch also removes get_timerstats() -- looks useless.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
process/timer.cpp | 50 +++++++++++++-------------------------------------
1 file changed, 13 insertions(+), 37 deletions(-)

diff --git a/process/timer.cpp b/process/timer.cpp
index 68fd31f..bb7f459 100644
--- a/process/timer.cpp
+++ b/process/timer.cpp
@@ -125,50 +125,26 @@ void clear_timers(void)
}
}

-bool get_timerstats(void)
-{
- FILE *file;
- file = fopen("/proc/timer_stats", "w");
- if (!file) {
- return false;
- }
- fprintf(file, "1\n");
- fclose(file);
- return true;
-}
-
bool timer::is_deferred(void)
{
- FILE *file;
- char line[4096];
+ FILE *file;
+ bool ret = false;
+ char line[4096];

- if (!get_timerstats()){
- return false;
- }
- file = fopen("/proc/timer_stats", "r");
+ file = fopen("/proc/timer_stats", "r");
if (!file) {
- return false;
+ return ret;
}

- while (file && !feof(file)) {
- char *c;
- if (fgets(line, 4096,file)== NULL)
- break;
- if (strstr(line, "total events"))
+ while (!feof(file)) {
+ if (fgets(line, 4096, file) == NULL)
break;
- if (!handler)
- break;
- if (strstr(line, handler)){
- c = strchr(line, ',');
- if (!c)
- continue;
- c--;
- if (*c == 'D') {
- fclose(file);
- return true;
- }
+ if (strstr(line, handler)) {
+ ret = (strstr(line, "D,") != NULL);
+ if (ret == true)
+ break;
}
}
fclose(file);
- return false;
-}
\ No newline at end of file
+ return ret;
+}
Sergey Senozhatsky
2012-04-24 20:52:15 UTC
Permalink
Timer creation makes powertop stuck with high CPU usage for a noticeable
amount of time, due to /proc/timer_stats file parsing.

Move member is_deferred() to static timer_is_deferred(const char*) function,
which gets called during timer() construction.

is_deferred() function returns member bool deferred variable instead,
preventing CPU consuming file lookup.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
process/timer.cpp | 45 +++++++++++++++++++++++++--------------------
process/timer.h | 1 +
2 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/process/timer.cpp b/process/timer.cpp
index bb7f459..8917490 100644
--- a/process/timer.cpp
+++ b/process/timer.cpp
@@ -35,11 +35,35 @@

using namespace std;

+static bool timer_is_deferred(const char *handler)
+{
+ FILE *file;
+ bool ret = false;
+ char line[4096];
+
+ file = fopen("/proc/timer_stats", "r");
+ if (!file) {
+ return ret;
+ }
+
+ while (!feof(file)) {
+ if (fgets(line, 4096, file) == NULL)
+ break;
+ if (strstr(line, handler)) {
+ ret = (strstr(line, "D,") != NULL);
+ if (ret == true)
+ break;
+ }
+ }
+ fclose(file);
+ return ret;
+}

timer::timer(unsigned long address) : power_consumer()
{
strncpy(handler, kernel_function(address), 31);
raw_count = 0;
+ deferred = timer_is_deferred(handler);
}


@@ -127,24 +151,5 @@ void clear_timers(void)

bool timer::is_deferred(void)
{
- FILE *file;
- bool ret = false;
- char line[4096];
-
- file = fopen("/proc/timer_stats", "r");
- if (!file) {
- return ret;
- }
-
- while (!feof(file)) {
- if (fgets(line, 4096, file) == NULL)
- break;
- if (strstr(line, handler)) {
- ret = (strstr(line, "D,") != NULL);
- if (ret == true)
- break;
- }
- }
- fclose(file);
- return ret;
+ return deferred;
}
diff --git a/process/timer.h b/process/timer.h
index 880fa26..7718c3b 100644
--- a/process/timer.h
+++ b/process/timer.h
@@ -34,6 +34,7 @@ class timer : public power_consumer {
public:
char handler[32];
int raw_count;
+ bool deferred;

timer(unsigned long timer_func);
Sergey Senozhatsky
2012-04-24 20:53:52 UTC
Permalink
Currently, w_display_cpu_pstates() and w_display_cpu_cstates()
are 90% similar functions with the only difference in abstract_cpu
calls: pstate vs. cstate.

This patch introduces helper functions:
- has_state_level() -- call has_pstate_level() or has_cstate_level()
- fill_state_name() -- call fill_pstate_name() or fill_cstate_name()
- fill_state_line() -- call fill_pstate_line() or fill_pstate_line()

actions are performed according to passed param: PSTATE or CSTATE.

This allows to merge implementations of w_display_cpu_pstates() and
w_display_cpu_cstates() into one function -- impl_w_display_cpu_states()
(which performs helpers calls with appropriate PSTATE or CSTATE flag).

w_display_cpu_pstates() and w_display_cpu_cstates() are still there,
but the only thing they do is
impl_w_display_cpu_states(PSTATE) or impl_w_display_cpu_states(CSTATE)
accordingly.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky-***@public.gmane.org>

---
cpu/cpu.cpp | 172 +++++++++++++++++++++--------------------------------------
cpu/cpu.h | 3 ++
2 files changed, 64 insertions(+), 111 deletions(-)

diff --git a/cpu/cpu.cpp b/cpu/cpu.cpp
index 756fe5e..5f62893 100644
--- a/cpu/cpu.cpp
+++ b/cpu/cpu.cpp
@@ -339,6 +339,46 @@ static const char *freq_class(int line)
return "cpu_even_req";
}

+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];
@@ -538,100 +578,6 @@ void report_display_cpu_cstates(void)
}
}

-void w_display_cpu_cstates(void)
-{
-#ifndef DISABLE_NCURSES
- WINDOW *win;
- char buffer[128];
- char linebuf[1024];
- unsigned int package, core, cpu;
- int line;
- class abstract_cpu *_package, * _core, * _cpu;
- int ctr = 0;
-
- 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;
-
- for (line = LEVEL_HEADER; line < 20; line++) {
- int first = 1;
- ctr = 0;
- linebuf[0] = 0;
- if (!_package->has_cstate_level(line))
- continue;
-
-
- buffer[0] = 0;
- if (first_pkg == 0) {
- strcat(linebuf, _package->fill_cstate_name(line, buffer));
- expand_string(linebuf, ctr+10);
- strcat(linebuf, _package->fill_cstate_line(line, buffer));
- }
- ctr += 20;
- expand_string(linebuf, ctr);
-
- strcat(linebuf, "| ");
- ctr += strlen("| ");
-
- if (!_core->can_collapse()) {
- buffer[0] = 0;
- strcat(linebuf, _core->fill_cstate_name(line, buffer));
- expand_string(linebuf, ctr + 10);
- strcat(linebuf, _core->fill_cstate_line(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, _cpu->fill_cstate_name(line, buffer));
- expand_string(linebuf, ctr + 10);
- first = 0;
- ctr += 12;
- }
- buffer[0] = 0;
- strcat(linebuf, _cpu->fill_cstate_line(line, buffer));
- ctr += 18;
- expand_string(linebuf, ctr);
-
- }
- strcat(linebuf, "\n");
- wprintw(win, "%s", linebuf);
- }
-
- wprintw(win, "\n");
- first_pkg++;
- }
-
-
- }
-#endif // DISABLE_NCURSES
-}
-
-
-
void report_display_cpu_pstates(void)
{
char buffer[512], buffer2[512];
@@ -826,9 +772,7 @@ void report_display_cpu_pstates(void)
fprintf(reportout.csv_report, "\n");
}

-
-
-void w_display_cpu_pstates(void)
+void impl_w_display_cpu_states(int state)
{
#ifndef DISABLE_NCURSES
WINDOW *win;
@@ -839,21 +783,23 @@ void w_display_cpu_pstates(void)
class abstract_cpu *_package, * _core, * _cpu;
int ctr = 0;

- win = get_ncurses_win("Frequency stats");
+ 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)
@@ -864,15 +810,14 @@ void w_display_cpu_pstates(void)
ctr = 0;
linebuf[0] = 0;

- if (!_package->has_pstate_level(line))
+ if (!has_state_level(_package, state, line))
continue;

-
buffer[0] = 0;
if (first_pkg == 0) {
- strcat(linebuf, _package->fill_pstate_name(line, buffer));
+ strcat(linebuf, fill_state_name(_package, state, line, buffer));
expand_string(linebuf, ctr + 10);
- strcat(linebuf, _package->fill_pstate_line(line, buffer));
+ strcat(linebuf, fill_state_line(_package, state, line, buffer));
}
ctr += 20;
expand_string(linebuf, ctr);
@@ -882,9 +827,9 @@ void w_display_cpu_pstates(void)

if (!_core->can_collapse()) {
buffer[0] = 0;
- strcat(linebuf, _core->fill_pstate_name(line, buffer));
+ strcat(linebuf, fill_state_name(_core, state, line, buffer));
expand_string(linebuf, ctr + 10);
- strcat(linebuf, _core->fill_pstate_line(line, buffer));
+ strcat(linebuf, fill_state_line(_core, state, line, buffer));
ctr += 20;
expand_string(linebuf, ctr);

@@ -898,13 +843,13 @@ void w_display_cpu_pstates(void)
continue;

if (first == 1) {
- strcat(linebuf, _cpu->fill_pstate_name(line, buffer));
+ strcat(linebuf, fill_state_name(_cpu, state, line, buffer));
expand_string(linebuf, ctr + 10);
first = 0;
ctr += 12;
}
buffer[0] = 0;
- strcat(linebuf, _cpu->fill_pstate_line(line, buffer));
+ strcat(linebuf, fill_state_line(_cpu, state, line, buffer));
ctr += 10;
expand_string(linebuf, ctr);

@@ -912,17 +857,22 @@ void w_display_cpu_pstates(void)
strcat(linebuf, "\n");
wprintw(win, "%s", linebuf);
}
-
wprintw(win, "\n");
first_pkg++;
}
-
-
}
#endif // DISABLE_NCURSES
}

+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__
diff --git a/cpu/cpu.h b/cpu/cpu.h
index f5898e9..b48ada9 100644
--- a/cpu/cpu.h
+++ b/cpu/cpu.h
@@ -39,6 +39,9 @@ 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];

Loading...