1*b47b5b34SRafael Vanoni /* 2*b47b5b34SRafael Vanoni * Copyright 2009, Intel Corporation 3*b47b5b34SRafael Vanoni * Copyright 2009, Sun Microsystems, Inc 4*b47b5b34SRafael Vanoni * 5*b47b5b34SRafael Vanoni * This file is part of PowerTOP 6*b47b5b34SRafael Vanoni * 7*b47b5b34SRafael Vanoni * This program file is free software; you can redistribute it and/or modify it 8*b47b5b34SRafael Vanoni * under the terms of the GNU General Public License as published by the 9*b47b5b34SRafael Vanoni * Free Software Foundation; version 2 of the License. 10*b47b5b34SRafael Vanoni * 11*b47b5b34SRafael Vanoni * This program is distributed in the hope that it will be useful, but WITHOUT 12*b47b5b34SRafael Vanoni * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*b47b5b34SRafael Vanoni * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14*b47b5b34SRafael Vanoni * for more details. 15*b47b5b34SRafael Vanoni * 16*b47b5b34SRafael Vanoni * You should have received a copy of the GNU General Public License 17*b47b5b34SRafael Vanoni * along with this program in a file named COPYING; if not, write to the 18*b47b5b34SRafael Vanoni * Free Software Foundation, Inc., 19*b47b5b34SRafael Vanoni * 51 Franklin Street, Fifth Floor, 20*b47b5b34SRafael Vanoni * Boston, MA 02110-1301 USA 21*b47b5b34SRafael Vanoni * 22*b47b5b34SRafael Vanoni * Authors: 23*b47b5b34SRafael Vanoni * Arjan van de Ven <arjan@linux.intel.com> 24*b47b5b34SRafael Vanoni * Eric C Saxe <eric.saxe@sun.com> 25*b47b5b34SRafael Vanoni * Aubrey Li <aubrey.li@intel.com> 26*b47b5b34SRafael Vanoni */ 27*b47b5b34SRafael Vanoni 28*b47b5b34SRafael Vanoni /* 29*b47b5b34SRafael Vanoni * GPL Disclaimer 30*b47b5b34SRafael Vanoni * 31*b47b5b34SRafael Vanoni * For the avoidance of doubt, except that if any license choice other 32*b47b5b34SRafael Vanoni * than GPL or LGPL is available it will apply instead, Sun elects to 33*b47b5b34SRafael Vanoni * use only the General Public License version 2 (GPLv2) at this time 34*b47b5b34SRafael Vanoni * for any software where a choice of GPL license versions is made 35*b47b5b34SRafael Vanoni * available with the language indicating that GPLv2 or any later 36*b47b5b34SRafael Vanoni * version may be used, or where a choice of which version of the GPL 37*b47b5b34SRafael Vanoni * is applied is otherwise unspecified. 38*b47b5b34SRafael Vanoni */ 39*b47b5b34SRafael Vanoni 40*b47b5b34SRafael Vanoni #include <stdlib.h> 41*b47b5b34SRafael Vanoni #include <string.h> 42*b47b5b34SRafael Vanoni #include <curses.h> 43*b47b5b34SRafael Vanoni #include "powertop.h" 44*b47b5b34SRafael Vanoni 45*b47b5b34SRafael Vanoni static WINDOW *title_bar_window; 46*b47b5b34SRafael Vanoni static WINDOW *cstate_window; 47*b47b5b34SRafael Vanoni static WINDOW *wakeup_window; 48*b47b5b34SRafael Vanoni static WINDOW *acpi_power_window; 49*b47b5b34SRafael Vanoni static WINDOW *eventstat_window; 50*b47b5b34SRafael Vanoni static WINDOW *suggestion_window; 51*b47b5b34SRafael Vanoni static WINDOW *status_bar_window; 52*b47b5b34SRafael Vanoni 53*b47b5b34SRafael Vanoni #define print(win, y, x, fmt, args...) \ 54*b47b5b34SRafael Vanoni if (PTOP_ON_DUMP) \ 55*b47b5b34SRafael Vanoni (void) printf(fmt, ## args); \ 56*b47b5b34SRafael Vanoni else \ 57*b47b5b34SRafael Vanoni (void) mvwprintw(win, y, x, fmt, ## args); 58*b47b5b34SRafael Vanoni 59*b47b5b34SRafael Vanoni char g_status_bar_slots[PTOP_BAR_NSLOTS][PTOP_BAR_LENGTH]; 60*b47b5b34SRafael Vanoni char g_suggestion_key; 61*b47b5b34SRafael Vanoni 62*b47b5b34SRafael Vanoni static int maxx, maxy; 63*b47b5b34SRafael Vanoni 64*b47b5b34SRafael Vanoni static void 65*b47b5b34SRafael Vanoni zap_windows(void) 66*b47b5b34SRafael Vanoni { 67*b47b5b34SRafael Vanoni if (title_bar_window) { 68*b47b5b34SRafael Vanoni (void) delwin(title_bar_window); 69*b47b5b34SRafael Vanoni title_bar_window = NULL; 70*b47b5b34SRafael Vanoni } 71*b47b5b34SRafael Vanoni if (cstate_window) { 72*b47b5b34SRafael Vanoni (void) delwin(cstate_window); 73*b47b5b34SRafael Vanoni cstate_window = NULL; 74*b47b5b34SRafael Vanoni } 75*b47b5b34SRafael Vanoni if (wakeup_window) { 76*b47b5b34SRafael Vanoni (void) delwin(wakeup_window); 77*b47b5b34SRafael Vanoni wakeup_window = NULL; 78*b47b5b34SRafael Vanoni } 79*b47b5b34SRafael Vanoni if (acpi_power_window) { 80*b47b5b34SRafael Vanoni (void) delwin(acpi_power_window); 81*b47b5b34SRafael Vanoni acpi_power_window = NULL; 82*b47b5b34SRafael Vanoni } 83*b47b5b34SRafael Vanoni if (eventstat_window) { 84*b47b5b34SRafael Vanoni (void) delwin(eventstat_window); 85*b47b5b34SRafael Vanoni eventstat_window = NULL; 86*b47b5b34SRafael Vanoni } 87*b47b5b34SRafael Vanoni if (suggestion_window) { 88*b47b5b34SRafael Vanoni (void) delwin(suggestion_window); 89*b47b5b34SRafael Vanoni suggestion_window = NULL; 90*b47b5b34SRafael Vanoni } 91*b47b5b34SRafael Vanoni if (status_bar_window) { 92*b47b5b34SRafael Vanoni (void) delwin(status_bar_window); 93*b47b5b34SRafael Vanoni status_bar_window = NULL; 94*b47b5b34SRafael Vanoni } 95*b47b5b34SRafael Vanoni } 96*b47b5b34SRafael Vanoni 97*b47b5b34SRafael Vanoni void 98*b47b5b34SRafael Vanoni cleanup_curses(void) 99*b47b5b34SRafael Vanoni { 100*b47b5b34SRafael Vanoni (void) endwin(); 101*b47b5b34SRafael Vanoni } 102*b47b5b34SRafael Vanoni 103*b47b5b34SRafael Vanoni /* 104*b47b5b34SRafael Vanoni * This part was re-written to be human readable and easy to modify. Please 105*b47b5b34SRafael Vanoni * try to keep it that way and help us save some time. 106*b47b5b34SRafael Vanoni * 107*b47b5b34SRafael Vanoni * Friendly reminder: 108*b47b5b34SRafael Vanoni * subwin(WINDOW *orig, int nlines, int ncols, int begin_y, int begin_x) 109*b47b5b34SRafael Vanoni */ 110*b47b5b34SRafael Vanoni void 111*b47b5b34SRafael Vanoni setup_windows(void) 112*b47b5b34SRafael Vanoni { 113*b47b5b34SRafael Vanoni /* 114*b47b5b34SRafael Vanoni * These variables are used to properly set the initial y position and 115*b47b5b34SRafael Vanoni * number of lines in each subwindow, as the number of supported CPU 116*b47b5b34SRafael Vanoni * states affects their placement. 117*b47b5b34SRafael Vanoni */ 118*b47b5b34SRafael Vanoni int cstate_lines, event_lines, pos_y; 119*b47b5b34SRafael Vanoni 120*b47b5b34SRafael Vanoni getmaxyx(stdscr, maxy, maxx); 121*b47b5b34SRafael Vanoni 122*b47b5b34SRafael Vanoni zap_windows(); 123*b47b5b34SRafael Vanoni 124*b47b5b34SRafael Vanoni cstate_lines = TITLE_LINE + max((g_max_cstate+1), g_npstates); 125*b47b5b34SRafael Vanoni 126*b47b5b34SRafael Vanoni pos_y = 0; 127*b47b5b34SRafael Vanoni title_bar_window = subwin(stdscr, SINGLE_LINE_SW, maxx, pos_y, 0); 128*b47b5b34SRafael Vanoni 129*b47b5b34SRafael Vanoni pos_y += NEXT_LINE + BLANK_LINE; 130*b47b5b34SRafael Vanoni cstate_window = subwin(stdscr, cstate_lines, maxx, pos_y, 0); 131*b47b5b34SRafael Vanoni 132*b47b5b34SRafael Vanoni pos_y += cstate_lines + BLANK_LINE; 133*b47b5b34SRafael Vanoni wakeup_window = subwin(stdscr, SINGLE_LINE_SW, maxx, pos_y, 0); 134*b47b5b34SRafael Vanoni 135*b47b5b34SRafael Vanoni pos_y += NEXT_LINE; 136*b47b5b34SRafael Vanoni acpi_power_window = subwin(stdscr, SINGLE_LINE_SW, maxx, pos_y, 0); 137*b47b5b34SRafael Vanoni 138*b47b5b34SRafael Vanoni pos_y += NEXT_LINE + BLANK_LINE; 139*b47b5b34SRafael Vanoni event_lines = maxy - SINGLE_LINE_SW - NEXT_LINE - LENGTH_SUGG_SW - 140*b47b5b34SRafael Vanoni pos_y; 141*b47b5b34SRafael Vanoni eventstat_window = subwin(stdscr, event_lines, maxx, pos_y, 0); 142*b47b5b34SRafael Vanoni 143*b47b5b34SRafael Vanoni pos_y += event_lines + NEXT_LINE; 144*b47b5b34SRafael Vanoni suggestion_window = subwin(stdscr, SINGLE_LINE_SW, maxx, pos_y, 0); 145*b47b5b34SRafael Vanoni 146*b47b5b34SRafael Vanoni pos_y += BLANK_LINE + NEXT_LINE; 147*b47b5b34SRafael Vanoni status_bar_window = subwin(stdscr, SINGLE_LINE_SW, maxx, pos_y, 0); 148*b47b5b34SRafael Vanoni 149*b47b5b34SRafael Vanoni (void) strcpy(g_status_bar_slots[0], _(" Q - Quit ")); 150*b47b5b34SRafael Vanoni (void) strcpy(g_status_bar_slots[1], _(" R - Refresh ")); 151*b47b5b34SRafael Vanoni 152*b47b5b34SRafael Vanoni (void) werase(stdscr); 153*b47b5b34SRafael Vanoni (void) wrefresh(status_bar_window); 154*b47b5b34SRafael Vanoni } 155*b47b5b34SRafael Vanoni 156*b47b5b34SRafael Vanoni void 157*b47b5b34SRafael Vanoni initialize_curses(void) 158*b47b5b34SRafael Vanoni { 159*b47b5b34SRafael Vanoni (void) initscr(); 160*b47b5b34SRafael Vanoni (void) start_color(); 161*b47b5b34SRafael Vanoni 162*b47b5b34SRafael Vanoni /* 163*b47b5b34SRafael Vanoni * Enable keyboard mapping 164*b47b5b34SRafael Vanoni */ 165*b47b5b34SRafael Vanoni (void) keypad(stdscr, TRUE); 166*b47b5b34SRafael Vanoni 167*b47b5b34SRafael Vanoni /* 168*b47b5b34SRafael Vanoni * Tell curses not to do NL->CR/NL on output 169*b47b5b34SRafael Vanoni */ 170*b47b5b34SRafael Vanoni (void) nonl(); 171*b47b5b34SRafael Vanoni 172*b47b5b34SRafael Vanoni /* 173*b47b5b34SRafael Vanoni * Take input chars one at a time, no wait for \n 174*b47b5b34SRafael Vanoni */ 175*b47b5b34SRafael Vanoni (void) cbreak(); 176*b47b5b34SRafael Vanoni 177*b47b5b34SRafael Vanoni /* 178*b47b5b34SRafael Vanoni * Dont echo input 179*b47b5b34SRafael Vanoni */ 180*b47b5b34SRafael Vanoni (void) noecho(); 181*b47b5b34SRafael Vanoni 182*b47b5b34SRafael Vanoni /* 183*b47b5b34SRafael Vanoni * Turn off cursor 184*b47b5b34SRafael Vanoni */ 185*b47b5b34SRafael Vanoni (void) curs_set(0); 186*b47b5b34SRafael Vanoni 187*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK); 188*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_HEADER_BAR, COLOR_BLACK, COLOR_WHITE); 189*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED); 190*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED); 191*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW); 192*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN); 193*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE); 194*b47b5b34SRafael Vanoni (void) init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK); 195*b47b5b34SRafael Vanoni 196*b47b5b34SRafael Vanoni (void) atexit(cleanup_curses); 197*b47b5b34SRafael Vanoni } 198*b47b5b34SRafael Vanoni 199*b47b5b34SRafael Vanoni void 200*b47b5b34SRafael Vanoni show_title_bar(void) 201*b47b5b34SRafael Vanoni { 202*b47b5b34SRafael Vanoni int i, x = 0, y = 0; 203*b47b5b34SRafael Vanoni char title_pad[10]; 204*b47b5b34SRafael Vanoni 205*b47b5b34SRafael Vanoni (void) wattrset(title_bar_window, COLOR_PAIR(PT_COLOR_HEADER_BAR)); 206*b47b5b34SRafael Vanoni (void) wbkgd(title_bar_window, COLOR_PAIR(PT_COLOR_HEADER_BAR)); 207*b47b5b34SRafael Vanoni (void) werase(title_bar_window); 208*b47b5b34SRafael Vanoni 209*b47b5b34SRafael Vanoni (void) snprintf(title_pad, 10, "%%%ds", 210*b47b5b34SRafael Vanoni (maxx - strlen(TITLE))/2 + strlen(TITLE)); 211*b47b5b34SRafael Vanoni /* LINTED: E_SEC_PRINTF_VAR_FMT */ 212*b47b5b34SRafael Vanoni print(title_bar_window, y, x, title_pad, TITLE); 213*b47b5b34SRafael Vanoni 214*b47b5b34SRafael Vanoni (void) wrefresh(title_bar_window); 215*b47b5b34SRafael Vanoni (void) werase(status_bar_window); 216*b47b5b34SRafael Vanoni 217*b47b5b34SRafael Vanoni for (i = 0; i < PTOP_BAR_NSLOTS; i++) { 218*b47b5b34SRafael Vanoni if (strlen(g_status_bar_slots[i]) == 0) 219*b47b5b34SRafael Vanoni continue; 220*b47b5b34SRafael Vanoni (void) wattron(status_bar_window, A_REVERSE); 221*b47b5b34SRafael Vanoni print(status_bar_window, y, x, "%s", g_status_bar_slots[i]); 222*b47b5b34SRafael Vanoni (void) wattroff(status_bar_window, A_REVERSE); 223*b47b5b34SRafael Vanoni x += strlen(g_status_bar_slots[i]) + 1; 224*b47b5b34SRafael Vanoni } 225*b47b5b34SRafael Vanoni (void) wnoutrefresh(status_bar_window); 226*b47b5b34SRafael Vanoni } 227*b47b5b34SRafael Vanoni 228*b47b5b34SRafael Vanoni void 229*b47b5b34SRafael Vanoni show_cstates(void) 230*b47b5b34SRafael Vanoni { 231*b47b5b34SRafael Vanoni char c[100]; 232*b47b5b34SRafael Vanoni int i; 233*b47b5b34SRafael Vanoni double total_pstates = 0.0, avg, res; 234*b47b5b34SRafael Vanoni uint64_t p0_speed, p1_speed; 235*b47b5b34SRafael Vanoni 236*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) { 237*b47b5b34SRafael Vanoni (void) werase(cstate_window); 238*b47b5b34SRafael Vanoni (void) wattrset(cstate_window, COLOR_PAIR(PT_COLOR_DEFAULT)); 239*b47b5b34SRafael Vanoni (void) wbkgd(cstate_window, COLOR_PAIR(PT_COLOR_DEFAULT)); 240*b47b5b34SRafael Vanoni } 241*b47b5b34SRafael Vanoni 242*b47b5b34SRafael Vanoni print(cstate_window, 0, 0, "%s\tAvg residency\n", g_msg_idle_state); 243*b47b5b34SRafael Vanoni res = (((double)g_cstate_info[0].total_time / g_total_c_time)) * 100; 244*b47b5b34SRafael Vanoni (void) sprintf(c, "C0 (cpu running)\t\t(%.1f%%)\n", (float)res); 245*b47b5b34SRafael Vanoni print(cstate_window, 1, 0, "%s", c); 246*b47b5b34SRafael Vanoni 247*b47b5b34SRafael Vanoni for (i = 1; i <= g_max_cstate; i++) { 248*b47b5b34SRafael Vanoni /* 249*b47b5b34SRafael Vanoni * In situations where the load is too intensive, the system 250*b47b5b34SRafael Vanoni * might not transition at all. 251*b47b5b34SRafael Vanoni */ 252*b47b5b34SRafael Vanoni if (g_cstate_info[i].events > 0) 253*b47b5b34SRafael Vanoni avg = (((double)g_cstate_info[i].total_time/ 254*b47b5b34SRafael Vanoni g_ncpus_observed)/g_cstate_info[i].events); 255*b47b5b34SRafael Vanoni else 256*b47b5b34SRafael Vanoni avg = 0; 257*b47b5b34SRafael Vanoni 258*b47b5b34SRafael Vanoni res = ((double)g_cstate_info[i].total_time/g_total_c_time) 259*b47b5b34SRafael Vanoni * 100; 260*b47b5b34SRafael Vanoni 261*b47b5b34SRafael Vanoni (void) sprintf(c, "C%d\t\t\t%.1fms\t(%.1f%%)\n", i, (float)avg, 262*b47b5b34SRafael Vanoni (float)res); 263*b47b5b34SRafael Vanoni print(cstate_window, i + 1, 0, "%s", c); 264*b47b5b34SRafael Vanoni } 265*b47b5b34SRafael Vanoni 266*b47b5b34SRafael Vanoni print(cstate_window, 0, 48, "%s", g_msg_freq_state); 267*b47b5b34SRafael Vanoni 268*b47b5b34SRafael Vanoni if (g_npstates < 2) { 269*b47b5b34SRafael Vanoni (void) sprintf(c, "%4lu Mhz\t%.1f%%", 270*b47b5b34SRafael Vanoni (long)g_pstate_info[0].speed, 100.0); 271*b47b5b34SRafael Vanoni print(cstate_window, 1, 48, "%s\n", c); 272*b47b5b34SRafael Vanoni } else { 273*b47b5b34SRafael Vanoni for (i = 0; i < g_npstates; i++) { 274*b47b5b34SRafael Vanoni total_pstates += (double)(g_pstate_info[i].total_time/ 275*b47b5b34SRafael Vanoni g_ncpus_observed/1000000); 276*b47b5b34SRafael Vanoni } 277*b47b5b34SRafael Vanoni 278*b47b5b34SRafael Vanoni /* 279*b47b5b34SRafael Vanoni * display ACPI_PSTATE from P(n) to P(1) 280*b47b5b34SRafael Vanoni */ 281*b47b5b34SRafael Vanoni for (i = 0; i < g_npstates - 1; i++) { 282*b47b5b34SRafael Vanoni (void) sprintf(c, "%4lu Mhz\t%.1f%%", 283*b47b5b34SRafael Vanoni (long)g_pstate_info[i].speed, 284*b47b5b34SRafael Vanoni 100 * (g_pstate_info[i].total_time/g_ncpus_observed/ 285*b47b5b34SRafael Vanoni 1000000/total_pstates)); 286*b47b5b34SRafael Vanoni print(cstate_window, i+1, 48, "%s\n", c); 287*b47b5b34SRafael Vanoni } 288*b47b5b34SRafael Vanoni 289*b47b5b34SRafael Vanoni /* 290*b47b5b34SRafael Vanoni * Display ACPI_PSTATE P0 according to if turbo 291*b47b5b34SRafael Vanoni * mode is supported 292*b47b5b34SRafael Vanoni */ 293*b47b5b34SRafael Vanoni if (g_turbo_supported) { 294*b47b5b34SRafael Vanoni p1_speed = g_pstate_info[g_npstates - 2].speed; 295*b47b5b34SRafael Vanoni 296*b47b5b34SRafael Vanoni /* 297*b47b5b34SRafael Vanoni * If g_turbo_ratio <= 1.0, it will be ignored. 298*b47b5b34SRafael Vanoni * we display P(0) as P(1) + 1. 299*b47b5b34SRafael Vanoni */ 300*b47b5b34SRafael Vanoni if (g_turbo_ratio <= 1.0) { 301*b47b5b34SRafael Vanoni p0_speed = p1_speed + 1; 302*b47b5b34SRafael Vanoni } else { 303*b47b5b34SRafael Vanoni /* 304*b47b5b34SRafael Vanoni * If g_turbo_ratio > 1.0, that means turbo 305*b47b5b34SRafael Vanoni * mode works. So, P(0) = ratio * P(1); 306*b47b5b34SRafael Vanoni */ 307*b47b5b34SRafael Vanoni p0_speed = (uint64_t)(p1_speed * g_turbo_ratio); 308*b47b5b34SRafael Vanoni if (p0_speed < (p1_speed + 1)) 309*b47b5b34SRafael Vanoni p0_speed = p1_speed + 1; 310*b47b5b34SRafael Vanoni } 311*b47b5b34SRafael Vanoni /* 312*b47b5b34SRafael Vanoni * Reset the ratio for the next round 313*b47b5b34SRafael Vanoni */ 314*b47b5b34SRafael Vanoni g_turbo_ratio = 0.0; 315*b47b5b34SRafael Vanoni 316*b47b5b34SRafael Vanoni /* 317*b47b5b34SRafael Vanoni * Setup the string for the display 318*b47b5b34SRafael Vanoni */ 319*b47b5b34SRafael Vanoni (void) sprintf(c, "%4lu Mhz(turbo)\t%.1f%%", 320*b47b5b34SRafael Vanoni (long)p0_speed, 321*b47b5b34SRafael Vanoni 100 * (g_pstate_info[i].total_time/ 322*b47b5b34SRafael Vanoni g_ncpus_observed/1000000/total_pstates)); 323*b47b5b34SRafael Vanoni } else { 324*b47b5b34SRafael Vanoni (void) sprintf(c, "%4lu Mhz\t%.1f%%", 325*b47b5b34SRafael Vanoni (long)g_pstate_info[i].speed, 326*b47b5b34SRafael Vanoni 100 * (g_pstate_info[i].total_time/ 327*b47b5b34SRafael Vanoni g_ncpus_observed/1000000/total_pstates)); 328*b47b5b34SRafael Vanoni } 329*b47b5b34SRafael Vanoni print(cstate_window, i+1, 48, "%s\n", c); 330*b47b5b34SRafael Vanoni } 331*b47b5b34SRafael Vanoni 332*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) 333*b47b5b34SRafael Vanoni (void) wnoutrefresh(cstate_window); 334*b47b5b34SRafael Vanoni } 335*b47b5b34SRafael Vanoni 336*b47b5b34SRafael Vanoni void 337*b47b5b34SRafael Vanoni show_acpi_power_line(uint32_t flag, double rate, double rem_cap, double cap, 338*b47b5b34SRafael Vanoni uint32_t state) 339*b47b5b34SRafael Vanoni { 340*b47b5b34SRafael Vanoni char buffer[1024]; 341*b47b5b34SRafael Vanoni 342*b47b5b34SRafael Vanoni (void) sprintf(buffer, _("no ACPI power usage estimate available")); 343*b47b5b34SRafael Vanoni 344*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) 345*b47b5b34SRafael Vanoni (void) werase(acpi_power_window); 346*b47b5b34SRafael Vanoni if (flag) { 347*b47b5b34SRafael Vanoni char *c; 348*b47b5b34SRafael Vanoni (void) sprintf(buffer, "Power usage (ACPI estimate): %.3fW", 349*b47b5b34SRafael Vanoni rate); 350*b47b5b34SRafael Vanoni (void) strcat(buffer, " "); 351*b47b5b34SRafael Vanoni c = &buffer[strlen(buffer)]; 352*b47b5b34SRafael Vanoni switch (state) { 353*b47b5b34SRafael Vanoni case 0: 354*b47b5b34SRafael Vanoni (void) sprintf(c, "(running on AC power, fully " 355*b47b5b34SRafael Vanoni "charged)"); 356*b47b5b34SRafael Vanoni break; 357*b47b5b34SRafael Vanoni case 1: 358*b47b5b34SRafael Vanoni (void) sprintf(c, "(discharging: %3.1f hours)", 359*b47b5b34SRafael Vanoni (uint32_t)rem_cap/rate); 360*b47b5b34SRafael Vanoni break; 361*b47b5b34SRafael Vanoni case 2: 362*b47b5b34SRafael Vanoni (void) sprintf(c, "(charging: %3.1f hours)", 363*b47b5b34SRafael Vanoni (uint32_t)(cap - rem_cap)/rate); 364*b47b5b34SRafael Vanoni break; 365*b47b5b34SRafael Vanoni case 4: 366*b47b5b34SRafael Vanoni (void) sprintf(c, "(##critically low battery power##)"); 367*b47b5b34SRafael Vanoni break; 368*b47b5b34SRafael Vanoni } 369*b47b5b34SRafael Vanoni 370*b47b5b34SRafael Vanoni } 371*b47b5b34SRafael Vanoni print(acpi_power_window, 0, 0, "%s\n", buffer); 372*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) 373*b47b5b34SRafael Vanoni (void) wnoutrefresh(acpi_power_window); 374*b47b5b34SRafael Vanoni } 375*b47b5b34SRafael Vanoni 376*b47b5b34SRafael Vanoni void 377*b47b5b34SRafael Vanoni show_wakeups(double interval) 378*b47b5b34SRafael Vanoni { 379*b47b5b34SRafael Vanoni char c[100]; 380*b47b5b34SRafael Vanoni int i, event_sum = 0; 381*b47b5b34SRafael Vanoni event_info_t *g_p_event = g_event_info; 382*b47b5b34SRafael Vanoni 383*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) { 384*b47b5b34SRafael Vanoni (void) werase(wakeup_window); 385*b47b5b34SRafael Vanoni (void) wbkgd(wakeup_window, COLOR_PAIR(PT_COLOR_RED)); 386*b47b5b34SRafael Vanoni (void) wattron(wakeup_window, A_BOLD); 387*b47b5b34SRafael Vanoni } 388*b47b5b34SRafael Vanoni 389*b47b5b34SRafael Vanoni /* 390*b47b5b34SRafael Vanoni * calculate the actual total event number 391*b47b5b34SRafael Vanoni */ 392*b47b5b34SRafael Vanoni for (i = 0; i < g_tog_p_events; i++, g_p_event++) 393*b47b5b34SRafael Vanoni event_sum += g_p_event->total_count; 394*b47b5b34SRafael Vanoni 395*b47b5b34SRafael Vanoni /* 396*b47b5b34SRafael Vanoni * g_total_events is the sum of the number of Cx->C0 transition, 397*b47b5b34SRafael Vanoni * So when the system is very busy, the idle thread will have no 398*b47b5b34SRafael Vanoni * chance or very seldom to be scheduled, this could cause >100% 399*b47b5b34SRafael Vanoni * event report. Re-assign g_total_events to the actual event 400*b47b5b34SRafael Vanoni * number is a way to avoid this issue. 401*b47b5b34SRafael Vanoni */ 402*b47b5b34SRafael Vanoni if (event_sum > g_total_events) 403*b47b5b34SRafael Vanoni g_total_events = event_sum; 404*b47b5b34SRafael Vanoni 405*b47b5b34SRafael Vanoni (void) sprintf(c, "Wakeups-from-idle per second: %4.1f\tinterval: " 406*b47b5b34SRafael Vanoni "%.1fs", (double)(g_total_events/interval), interval); 407*b47b5b34SRafael Vanoni print(wakeup_window, 0, 0, "%s\n", c); 408*b47b5b34SRafael Vanoni 409*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) 410*b47b5b34SRafael Vanoni (void) wnoutrefresh(wakeup_window); 411*b47b5b34SRafael Vanoni } 412*b47b5b34SRafael Vanoni 413*b47b5b34SRafael Vanoni void 414*b47b5b34SRafael Vanoni show_eventstats(double interval) 415*b47b5b34SRafael Vanoni { 416*b47b5b34SRafael Vanoni char c[100]; 417*b47b5b34SRafael Vanoni int i; 418*b47b5b34SRafael Vanoni double events; 419*b47b5b34SRafael Vanoni event_info_t *g_p_event = g_event_info; 420*b47b5b34SRafael Vanoni 421*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) { 422*b47b5b34SRafael Vanoni (void) werase(eventstat_window); 423*b47b5b34SRafael Vanoni (void) wattrset(eventstat_window, COLOR_PAIR(PT_COLOR_DEFAULT)); 424*b47b5b34SRafael Vanoni (void) wbkgd(eventstat_window, COLOR_PAIR(PT_COLOR_DEFAULT)); 425*b47b5b34SRafael Vanoni } 426*b47b5b34SRafael Vanoni 427*b47b5b34SRafael Vanoni /* 428*b47b5b34SRafael Vanoni * Sort the event report list 429*b47b5b34SRafael Vanoni */ 430*b47b5b34SRafael Vanoni if (g_tog_p_events > EVENT_NUM_MAX) 431*b47b5b34SRafael Vanoni g_tog_p_events = EVENT_NUM_MAX; 432*b47b5b34SRafael Vanoni 433*b47b5b34SRafael Vanoni qsort((void *)g_event_info, g_tog_p_events, sizeof (event_info_t), 434*b47b5b34SRafael Vanoni event_compare); 435*b47b5b34SRafael Vanoni 436*b47b5b34SRafael Vanoni if (PTOP_ON_CPU) 437*b47b5b34SRafael Vanoni (void) sprintf(c, "Top causes for wakeups on CPU %d:\n", 438*b47b5b34SRafael Vanoni g_observed_cpu); 439*b47b5b34SRafael Vanoni else 440*b47b5b34SRafael Vanoni (void) sprintf(c, "Top causes for wakeups:\n"); 441*b47b5b34SRafael Vanoni 442*b47b5b34SRafael Vanoni print(eventstat_window, 0, 0, "%s", c); 443*b47b5b34SRafael Vanoni 444*b47b5b34SRafael Vanoni for (i = 0; i < g_tog_p_events; i++, g_p_event++) { 445*b47b5b34SRafael Vanoni 446*b47b5b34SRafael Vanoni if (g_total_events > 0 && g_p_event->total_count > 0) 447*b47b5b34SRafael Vanoni events = (double)g_p_event->total_count/ 448*b47b5b34SRafael Vanoni (double)g_total_events; 449*b47b5b34SRafael Vanoni else 450*b47b5b34SRafael Vanoni continue; 451*b47b5b34SRafael Vanoni 452*b47b5b34SRafael Vanoni (void) sprintf(c, "%4.1f%% (%5.1f)", 100 * events, 453*b47b5b34SRafael Vanoni (double)g_p_event->total_count/interval); 454*b47b5b34SRafael Vanoni print(eventstat_window, i+1, 0, "%s", c); 455*b47b5b34SRafael Vanoni print(eventstat_window, i+1, 16, "%20s :", 456*b47b5b34SRafael Vanoni g_p_event->offender_name); 457*b47b5b34SRafael Vanoni print(eventstat_window, i+1, 40, "%-64s\n", 458*b47b5b34SRafael Vanoni g_p_event->offense_name); 459*b47b5b34SRafael Vanoni } 460*b47b5b34SRafael Vanoni 461*b47b5b34SRafael Vanoni if (!PTOP_ON_DUMP) 462*b47b5b34SRafael Vanoni (void) wnoutrefresh(eventstat_window); 463*b47b5b34SRafael Vanoni } 464*b47b5b34SRafael Vanoni 465*b47b5b34SRafael Vanoni void 466*b47b5b34SRafael Vanoni show_suggestion(char *sug) 467*b47b5b34SRafael Vanoni { 468*b47b5b34SRafael Vanoni (void) werase(suggestion_window); 469*b47b5b34SRafael Vanoni print(suggestion_window, 0, 0, "%s", sug); 470*b47b5b34SRafael Vanoni (void) wnoutrefresh(suggestion_window); 471*b47b5b34SRafael Vanoni } 472*b47b5b34SRafael Vanoni 473*b47b5b34SRafael Vanoni void 474*b47b5b34SRafael Vanoni update_windows(void) 475*b47b5b34SRafael Vanoni { 476*b47b5b34SRafael Vanoni (void) doupdate(); 477*b47b5b34SRafael Vanoni } 478