xref: /titanic_53/usr/src/cmd/powertop/common/display.c (revision b47b5b34b42fa8056577c43496cdb99a4c99f8d7)
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