xref: /titanic_50/usr/src/cmd/powertop/common/powertop.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 <getopt.h>
41*b47b5b34SRafael Vanoni #include <unistd.h>
42*b47b5b34SRafael Vanoni #include <stdio.h>
43*b47b5b34SRafael Vanoni #include <stdlib.h>
44*b47b5b34SRafael Vanoni #include <string.h>
45*b47b5b34SRafael Vanoni #include <ctype.h>
46*b47b5b34SRafael Vanoni #include <locale.h>
47*b47b5b34SRafael Vanoni #include "powertop.h"
48*b47b5b34SRafael Vanoni 
49*b47b5b34SRafael Vanoni /*
50*b47b5b34SRafael Vanoni  * Global variables, see powertop.h for comments and extern declarations.
51*b47b5b34SRafael Vanoni  * These are ordered by type, grouped by usage.
52*b47b5b34SRafael Vanoni  */
53*b47b5b34SRafael Vanoni double 			g_ticktime, g_ticktime_usr;
54*b47b5b34SRafael Vanoni double 			g_interval;
55*b47b5b34SRafael Vanoni double			g_displaytime;
56*b47b5b34SRafael Vanoni 
57*b47b5b34SRafael Vanoni int			g_bit_depth;
58*b47b5b34SRafael Vanoni int 			g_total_events, g_tog_p_events;
59*b47b5b34SRafael Vanoni int			g_npstates, g_max_cstate, g_longest_cstate;
60*b47b5b34SRafael Vanoni uint_t			g_ncpus;
61*b47b5b34SRafael Vanoni uint_t			g_ncpus_observed;
62*b47b5b34SRafael Vanoni 
63*b47b5b34SRafael Vanoni processorid_t 		*g_cpu_table;
64*b47b5b34SRafael Vanoni 
65*b47b5b34SRafael Vanoni hrtime_t		g_total_c_time;
66*b47b5b34SRafael Vanoni 
67*b47b5b34SRafael Vanoni uchar_t			g_op_mode;
68*b47b5b34SRafael Vanoni boolean_t		g_gui;
69*b47b5b34SRafael Vanoni uint_t			g_observed_cpu;
70*b47b5b34SRafael Vanoni 
71*b47b5b34SRafael Vanoni event_info_t    	g_event_info[EVENT_NUM_MAX];
72*b47b5b34SRafael Vanoni event_info_t		*g_p_event;
73*b47b5b34SRafael Vanoni state_info_t		g_cstate_info[NSTATES];
74*b47b5b34SRafael Vanoni freq_state_info_t	g_pstate_info[NSTATES];
75*b47b5b34SRafael Vanoni cpu_power_info_t	*g_cpu_power_states;
76*b47b5b34SRafael Vanoni suggestion_func 	*g_suggestion_activate;
77*b47b5b34SRafael Vanoni 
78*b47b5b34SRafael Vanoni boolean_t		g_turbo_supported;
79*b47b5b34SRafael Vanoni 
80*b47b5b34SRafael Vanoni uint_t			g_argc;
81*b47b5b34SRafael Vanoni char			**g_argv;
82*b47b5b34SRafael Vanoni 
83*b47b5b34SRafael Vanoni char			*optarg;
84*b47b5b34SRafael Vanoni 
85*b47b5b34SRafael Vanoni static const int	true = 1;
86*b47b5b34SRafael Vanoni 
87*b47b5b34SRafael Vanoni int
88*b47b5b34SRafael Vanoni main(int argc, char **argv)
89*b47b5b34SRafael Vanoni {
90*b47b5b34SRafael Vanoni 	hrtime_t 	last, now;
91*b47b5b34SRafael Vanoni 	uint_t		features = 0, user_interval = 0;
92*b47b5b34SRafael Vanoni 	int		ncursesinited = 0, index2 = 0, c, ret, dump_count = 0;
93*b47b5b34SRafael Vanoni 	double		last_time;
94*b47b5b34SRafael Vanoni 	char		*endptr;
95*b47b5b34SRafael Vanoni 
96*b47b5b34SRafael Vanoni 	static struct option opts[] = {
97*b47b5b34SRafael Vanoni 		{ "dump", 1, NULL, 'd' },
98*b47b5b34SRafael Vanoni 		{ "time", 1, NULL, 't' },
99*b47b5b34SRafael Vanoni 		{ "help", 0, NULL, 'h' },
100*b47b5b34SRafael Vanoni 		{ "cpu", 1, NULL, 'c' },
101*b47b5b34SRafael Vanoni 		{ "verbose", 0, NULL, 'v' },
102*b47b5b34SRafael Vanoni 		{ 0, 0, NULL, 0 }
103*b47b5b34SRafael Vanoni 	};
104*b47b5b34SRafael Vanoni 
105*b47b5b34SRafael Vanoni 	(void) setlocale(LC_ALL, "");
106*b47b5b34SRafael Vanoni 	(void) bindtextdomain("powertop", "/usr/share/locale");
107*b47b5b34SRafael Vanoni 	(void) textdomain("powertop");
108*b47b5b34SRafael Vanoni 
109*b47b5b34SRafael Vanoni 	pt_set_progname(argv[0]);
110*b47b5b34SRafael Vanoni 
111*b47b5b34SRafael Vanoni 	/*
112*b47b5b34SRafael Vanoni 	 * Enumerate the system's CPUs
113*b47b5b34SRafael Vanoni 	 * Populate cpu_table, g_ncpus
114*b47b5b34SRafael Vanoni 	 */
115*b47b5b34SRafael Vanoni 	if ((g_ncpus = g_ncpus_observed = enumerate_cpus()) == 0)
116*b47b5b34SRafael Vanoni 		exit(EXIT_FAILURE);
117*b47b5b34SRafael Vanoni 
118*b47b5b34SRafael Vanoni 	if ((g_bit_depth = get_bit_depth()) < 0)
119*b47b5b34SRafael Vanoni 		exit(EXIT_FAILURE);
120*b47b5b34SRafael Vanoni 
121*b47b5b34SRafael Vanoni 	g_ticktime = g_ticktime_usr = INTERVAL_DEFAULT;
122*b47b5b34SRafael Vanoni 	g_displaytime 	= 0.0;
123*b47b5b34SRafael Vanoni 	g_op_mode	= PTOP_MODE_DEFAULT;
124*b47b5b34SRafael Vanoni 	g_gui		= B_FALSE;
125*b47b5b34SRafael Vanoni 	g_max_cstate	= 0;
126*b47b5b34SRafael Vanoni 	g_argv		= NULL;
127*b47b5b34SRafael Vanoni 	g_argc		= 0;
128*b47b5b34SRafael Vanoni 	g_observed_cpu	= 0;
129*b47b5b34SRafael Vanoni 	g_turbo_supported = B_FALSE;
130*b47b5b34SRafael Vanoni 
131*b47b5b34SRafael Vanoni 	while ((c = getopt_long(argc, argv, "d:t:h:vc:", opts, &index2))
132*b47b5b34SRafael Vanoni 	    != EOF) {
133*b47b5b34SRafael Vanoni 		if (c == -1)
134*b47b5b34SRafael Vanoni 			break;
135*b47b5b34SRafael Vanoni 
136*b47b5b34SRafael Vanoni 		switch (c) {
137*b47b5b34SRafael Vanoni 		case 'd':
138*b47b5b34SRafael Vanoni 			if (PTOP_ON_DUMP)
139*b47b5b34SRafael Vanoni 				usage();
140*b47b5b34SRafael Vanoni 
141*b47b5b34SRafael Vanoni 			g_op_mode |= PTOP_MODE_DUMP;
142*b47b5b34SRafael Vanoni 			dump_count = (int)strtod(optarg, &endptr);
143*b47b5b34SRafael Vanoni 
144*b47b5b34SRafael Vanoni 			if (dump_count <= 0 || *endptr != NULL)
145*b47b5b34SRafael Vanoni 				usage();
146*b47b5b34SRafael Vanoni 			break;
147*b47b5b34SRafael Vanoni 		case 't':
148*b47b5b34SRafael Vanoni 			if (user_interval)
149*b47b5b34SRafael Vanoni 				usage();
150*b47b5b34SRafael Vanoni 
151*b47b5b34SRafael Vanoni 			user_interval = 1;
152*b47b5b34SRafael Vanoni 			g_ticktime = g_ticktime_usr = (double)strtod(optarg,
153*b47b5b34SRafael Vanoni 			    &endptr);
154*b47b5b34SRafael Vanoni 
155*b47b5b34SRafael Vanoni 			if (*endptr != NULL || g_ticktime < 1 ||
156*b47b5b34SRafael Vanoni 			    g_ticktime > INTERVAL_MAX)
157*b47b5b34SRafael Vanoni 				usage();
158*b47b5b34SRafael Vanoni 			break;
159*b47b5b34SRafael Vanoni 		case 'v':
160*b47b5b34SRafael Vanoni 			if (PTOP_ON_CPU || PTOP_ON_VERBOSE)
161*b47b5b34SRafael Vanoni 				usage();
162*b47b5b34SRafael Vanoni 
163*b47b5b34SRafael Vanoni 			g_op_mode |= PTOP_MODE_VERBOSE;
164*b47b5b34SRafael Vanoni 			break;
165*b47b5b34SRafael Vanoni 		case 'c':
166*b47b5b34SRafael Vanoni 			if (PTOP_ON_CPU || PTOP_ON_VERBOSE)
167*b47b5b34SRafael Vanoni 				usage();
168*b47b5b34SRafael Vanoni 
169*b47b5b34SRafael Vanoni 			g_op_mode |= PTOP_MODE_CPU;
170*b47b5b34SRafael Vanoni 			g_observed_cpu = (uint_t)strtod(optarg, &endptr);
171*b47b5b34SRafael Vanoni 
172*b47b5b34SRafael Vanoni 			if (g_observed_cpu >= g_ncpus)
173*b47b5b34SRafael Vanoni 				usage();
174*b47b5b34SRafael Vanoni 
175*b47b5b34SRafael Vanoni 			g_argc = 1;
176*b47b5b34SRafael Vanoni 			g_ncpus_observed = 1;
177*b47b5b34SRafael Vanoni 
178*b47b5b34SRafael Vanoni 			if ((g_argv = malloc(sizeof (char *))) == NULL)
179*b47b5b34SRafael Vanoni 				return (EXIT_FAILURE);
180*b47b5b34SRafael Vanoni 
181*b47b5b34SRafael Vanoni 			if ((*g_argv = malloc(sizeof (char) * 5)) == NULL)
182*b47b5b34SRafael Vanoni 				return (EXIT_FAILURE);
183*b47b5b34SRafael Vanoni 
184*b47b5b34SRafael Vanoni 			(void) snprintf(*g_argv, 5, "%d\0", g_observed_cpu);
185*b47b5b34SRafael Vanoni 			break;
186*b47b5b34SRafael Vanoni 		case 'h':
187*b47b5b34SRafael Vanoni 		default:
188*b47b5b34SRafael Vanoni 			usage();
189*b47b5b34SRafael Vanoni 			return (EXIT_USAGE);
190*b47b5b34SRafael Vanoni 		}
191*b47b5b34SRafael Vanoni 	}
192*b47b5b34SRafael Vanoni 
193*b47b5b34SRafael Vanoni 	if (optind < argc) {
194*b47b5b34SRafael Vanoni 		usage();
195*b47b5b34SRafael Vanoni 	}
196*b47b5b34SRafael Vanoni 
197*b47b5b34SRafael Vanoni 	(void) printf("%s   %s\n\n", TITLE, COPYRIGHT_INTEL);
198*b47b5b34SRafael Vanoni 
199*b47b5b34SRafael Vanoni 	/*
200*b47b5b34SRafael Vanoni 	 * If the system is running on battery, find out what's
201*b47b5b34SRafael Vanoni 	 * the kstat module for it
202*b47b5b34SRafael Vanoni 	 */
203*b47b5b34SRafael Vanoni 	battery_mod_lookup();
204*b47b5b34SRafael Vanoni 
205*b47b5b34SRafael Vanoni 	/* Prepare C-state statistics */
206*b47b5b34SRafael Vanoni 	ret = pt_cpuidle_stat_prepare();
207*b47b5b34SRafael Vanoni 	if (ret == 0)
208*b47b5b34SRafael Vanoni 		features |= FEATURE_CSTATE;
209*b47b5b34SRafael Vanoni 	else
210*b47b5b34SRafael Vanoni 		/*
211*b47b5b34SRafael Vanoni 		 * PowerTop was unable to run a DTrace program,
212*b47b5b34SRafael Vanoni 		 * most likely for lack of permissions.
213*b47b5b34SRafael Vanoni 		 */
214*b47b5b34SRafael Vanoni 		exit(EXIT_FAILURE);
215*b47b5b34SRafael Vanoni 
216*b47b5b34SRafael Vanoni 	/* Prepare P-state statistics */
217*b47b5b34SRafael Vanoni 	if (pt_cpufreq_stat_prepare() == 0)
218*b47b5b34SRafael Vanoni 		features |= FEATURE_PSTATE;
219*b47b5b34SRafael Vanoni 
220*b47b5b34SRafael Vanoni 	/* Prepare event statistics */
221*b47b5b34SRafael Vanoni 	if (pt_events_stat_prepare() != -1)
222*b47b5b34SRafael Vanoni 		features |= FEATURE_EVENTS;
223*b47b5b34SRafael Vanoni 
224*b47b5b34SRafael Vanoni 	/* Prepare turbo statistics */
225*b47b5b34SRafael Vanoni 	if (pt_turbo_stat_prepare() == 0) {
226*b47b5b34SRafael Vanoni 		features |= FEATURE_TURBO;
227*b47b5b34SRafael Vanoni 	}
228*b47b5b34SRafael Vanoni 
229*b47b5b34SRafael Vanoni 	(void) printf(_("Collecting data for %.2f second(s) \n"),
230*b47b5b34SRafael Vanoni 	    (float)g_ticktime);
231*b47b5b34SRafael Vanoni 
232*b47b5b34SRafael Vanoni 	if (!PTOP_ON_DUMP)
233*b47b5b34SRafael Vanoni 		g_gui = B_TRUE;
234*b47b5b34SRafael Vanoni 
235*b47b5b34SRafael Vanoni 	last = gethrtime();
236*b47b5b34SRafael Vanoni 
237*b47b5b34SRafael Vanoni 	while (true) {
238*b47b5b34SRafael Vanoni 		fd_set 	rfds;
239*b47b5b34SRafael Vanoni 		struct 	timeval tv;
240*b47b5b34SRafael Vanoni 		int 	key, reinit = 0;
241*b47b5b34SRafael Vanoni 		char 	keychar;
242*b47b5b34SRafael Vanoni 
243*b47b5b34SRafael Vanoni 		/*
244*b47b5b34SRafael Vanoni 		 * Sleep for a while waiting either for input (if we're not
245*b47b5b34SRafael Vanoni 		 * in dump mode) or for the timeout to elapse
246*b47b5b34SRafael Vanoni 		 */
247*b47b5b34SRafael Vanoni 		FD_ZERO(&rfds);
248*b47b5b34SRafael Vanoni 		FD_SET(0, &rfds);
249*b47b5b34SRafael Vanoni 
250*b47b5b34SRafael Vanoni 		tv.tv_sec 	= (long)g_ticktime;
251*b47b5b34SRafael Vanoni 		tv.tv_usec 	= (long)((g_ticktime - tv.tv_sec) * 1000000);
252*b47b5b34SRafael Vanoni 
253*b47b5b34SRafael Vanoni 		if (!PTOP_ON_DUMP)
254*b47b5b34SRafael Vanoni 			key = select(1, &rfds, NULL, NULL, &tv);
255*b47b5b34SRafael Vanoni 		else
256*b47b5b34SRafael Vanoni 			key = select(1, NULL, NULL, NULL, &tv);
257*b47b5b34SRafael Vanoni 
258*b47b5b34SRafael Vanoni 		now 		= gethrtime();
259*b47b5b34SRafael Vanoni 
260*b47b5b34SRafael Vanoni 		g_interval 	= (double)(now - last)/NANOSEC;
261*b47b5b34SRafael Vanoni 		last 		= now;
262*b47b5b34SRafael Vanoni 
263*b47b5b34SRafael Vanoni 		g_tog_p_events 	= 0;
264*b47b5b34SRafael Vanoni 		g_total_events 	= 0;
265*b47b5b34SRafael Vanoni 
266*b47b5b34SRafael Vanoni 		(void) memset(g_event_info,
267*b47b5b34SRafael Vanoni 		    EVENT_NUM_MAX * sizeof (event_info_t), 0);
268*b47b5b34SRafael Vanoni 		(void) memset(g_cstate_info, 2 * sizeof (state_info_t), 0);
269*b47b5b34SRafael Vanoni 
270*b47b5b34SRafael Vanoni 		/* Collect idle state transition stats */
271*b47b5b34SRafael Vanoni 		if (features & FEATURE_CSTATE &&
272*b47b5b34SRafael Vanoni 		    pt_cpuidle_stat_collect(g_interval) < 0) {
273*b47b5b34SRafael Vanoni 			/* Reinitialize C-state statistics */
274*b47b5b34SRafael Vanoni 			if (pt_cpuidle_stat_prepare() != 0)
275*b47b5b34SRafael Vanoni 				exit(EXIT_FAILURE);
276*b47b5b34SRafael Vanoni 
277*b47b5b34SRafael Vanoni 			reinit = 1;
278*b47b5b34SRafael Vanoni 		}
279*b47b5b34SRafael Vanoni 
280*b47b5b34SRafael Vanoni 		/* Collect frequency change stats */
281*b47b5b34SRafael Vanoni 		if (features & FEATURE_PSTATE &&
282*b47b5b34SRafael Vanoni 		    pt_cpufreq_stat_collect(g_interval) < 0) {
283*b47b5b34SRafael Vanoni 			/* Reinitialize P-state statistics */
284*b47b5b34SRafael Vanoni 			if (pt_cpufreq_stat_prepare() != 0)
285*b47b5b34SRafael Vanoni 				exit(EXIT_FAILURE);
286*b47b5b34SRafael Vanoni 
287*b47b5b34SRafael Vanoni 			reinit = 1;
288*b47b5b34SRafael Vanoni 		}
289*b47b5b34SRafael Vanoni 
290*b47b5b34SRafael Vanoni 		/* Collect event statistics */
291*b47b5b34SRafael Vanoni 		if (features & FEATURE_EVENTS &&
292*b47b5b34SRafael Vanoni 		    pt_events_stat_collect() < 0) {
293*b47b5b34SRafael Vanoni 			/* Reinitialize event statistics */
294*b47b5b34SRafael Vanoni 			if (pt_events_stat_prepare() != 0)
295*b47b5b34SRafael Vanoni 				exit(EXIT_FAILURE);
296*b47b5b34SRafael Vanoni 
297*b47b5b34SRafael Vanoni 			reinit = 1;
298*b47b5b34SRafael Vanoni 		}
299*b47b5b34SRafael Vanoni 
300*b47b5b34SRafael Vanoni 		if (reinit)
301*b47b5b34SRafael Vanoni 			continue;
302*b47b5b34SRafael Vanoni 
303*b47b5b34SRafael Vanoni 		/* Collect turbo statistics */
304*b47b5b34SRafael Vanoni 		if (features & FEATURE_TURBO &&
305*b47b5b34SRafael Vanoni 		    pt_turbo_stat_collect() < 0) {
306*b47b5b34SRafael Vanoni 			exit(EXIT_FAILURE);
307*b47b5b34SRafael Vanoni 		}
308*b47b5b34SRafael Vanoni 
309*b47b5b34SRafael Vanoni 		/*
310*b47b5b34SRafael Vanoni 		 * Initialize curses if we're not dumping and
311*b47b5b34SRafael Vanoni 		 * haven't already done it
312*b47b5b34SRafael Vanoni 		 */
313*b47b5b34SRafael Vanoni 		if (!PTOP_ON_DUMP) {
314*b47b5b34SRafael Vanoni 			if (!ncursesinited) {
315*b47b5b34SRafael Vanoni 				initialize_curses();
316*b47b5b34SRafael Vanoni 				ncursesinited++;
317*b47b5b34SRafael Vanoni 			}
318*b47b5b34SRafael Vanoni 			setup_windows();
319*b47b5b34SRafael Vanoni 			show_title_bar();
320*b47b5b34SRafael Vanoni 		}
321*b47b5b34SRafael Vanoni 
322*b47b5b34SRafael Vanoni 		/* Show CPU power states */
323*b47b5b34SRafael Vanoni 		if (features & FEATURE_CSTATE)
324*b47b5b34SRafael Vanoni 			show_cstates();
325*b47b5b34SRafael Vanoni 
326*b47b5b34SRafael Vanoni 		/* Show wakeups events affecting PM */
327*b47b5b34SRafael Vanoni 		if (features & FEATURE_EVENTS) {
328*b47b5b34SRafael Vanoni 			show_wakeups(g_interval);
329*b47b5b34SRafael Vanoni 			show_eventstats(g_interval);
330*b47b5b34SRafael Vanoni 		}
331*b47b5b34SRafael Vanoni 
332*b47b5b34SRafael Vanoni 		print_battery();
333*b47b5b34SRafael Vanoni 
334*b47b5b34SRafael Vanoni 		g_displaytime = g_displaytime - g_ticktime;
335*b47b5b34SRafael Vanoni 
336*b47b5b34SRafael Vanoni 		if (key && !PTOP_ON_DUMP) {
337*b47b5b34SRafael Vanoni 			keychar = toupper(fgetc(stdin));
338*b47b5b34SRafael Vanoni 
339*b47b5b34SRafael Vanoni 			switch (keychar) {
340*b47b5b34SRafael Vanoni 			case 'Q':
341*b47b5b34SRafael Vanoni 				cleanup_curses();
342*b47b5b34SRafael Vanoni 				exit(EXIT_SUCCESS);
343*b47b5b34SRafael Vanoni 				break;
344*b47b5b34SRafael Vanoni 			case 'R':
345*b47b5b34SRafael Vanoni 				g_ticktime = 3;
346*b47b5b34SRafael Vanoni 				break;
347*b47b5b34SRafael Vanoni 			}
348*b47b5b34SRafael Vanoni 			if (keychar == g_suggestion_key &&
349*b47b5b34SRafael Vanoni 			    g_suggestion_activate) {
350*b47b5b34SRafael Vanoni 				g_suggestion_activate();
351*b47b5b34SRafael Vanoni 				g_displaytime = -1.0;
352*b47b5b34SRafael Vanoni 			}
353*b47b5b34SRafael Vanoni 		}
354*b47b5b34SRafael Vanoni 		reset_suggestions();
355*b47b5b34SRafael Vanoni 
356*b47b5b34SRafael Vanoni 		/* suggests PM */
357*b47b5b34SRafael Vanoni 		if (geteuid() == 0) {
358*b47b5b34SRafael Vanoni 			suggest_p_state();
359*b47b5b34SRafael Vanoni 		} else {
360*b47b5b34SRafael Vanoni 			suggest_as_root();
361*b47b5b34SRafael Vanoni 		}
362*b47b5b34SRafael Vanoni 
363*b47b5b34SRafael Vanoni 		if (dump_count)
364*b47b5b34SRafael Vanoni 			dump_count--;
365*b47b5b34SRafael Vanoni 
366*b47b5b34SRafael Vanoni 		/* Exits if user requested a dump */
367*b47b5b34SRafael Vanoni 		if (PTOP_ON_DUMP && !dump_count) {
368*b47b5b34SRafael Vanoni 			print_all_suggestions();
369*b47b5b34SRafael Vanoni 			exit(EXIT_SUCCESS);
370*b47b5b34SRafael Vanoni 		}
371*b47b5b34SRafael Vanoni 
372*b47b5b34SRafael Vanoni 		/* No key pressed, will suggest something */
373*b47b5b34SRafael Vanoni 		if (!key && !dump_count)
374*b47b5b34SRafael Vanoni 			pick_suggestion();
375*b47b5b34SRafael Vanoni 
376*b47b5b34SRafael Vanoni 		/* Refresh display */
377*b47b5b34SRafael Vanoni 		if (!PTOP_ON_DUMP) {
378*b47b5b34SRafael Vanoni 			show_title_bar();
379*b47b5b34SRafael Vanoni 			update_windows();
380*b47b5b34SRafael Vanoni 		}
381*b47b5b34SRafael Vanoni 
382*b47b5b34SRafael Vanoni 		/*
383*b47b5b34SRafael Vanoni 		 * Update the interval based on how long the CPU was in the
384*b47b5b34SRafael Vanoni 		 * longest c-state during the last snapshot. If the user
385*b47b5b34SRafael Vanoni 		 * specified an interval we skip this bit and keep it fixed.
386*b47b5b34SRafael Vanoni 		 */
387*b47b5b34SRafael Vanoni 		last_time = (((double)g_cstate_info[g_longest_cstate].total_time
388*b47b5b34SRafael Vanoni 		    /g_ncpus)/g_cstate_info[g_longest_cstate].events);
389*b47b5b34SRafael Vanoni 
390*b47b5b34SRafael Vanoni 		if (!user_interval)
391*b47b5b34SRafael Vanoni 			if (last_time < INTERVAL_DEFAULT ||
392*b47b5b34SRafael Vanoni 			    (g_total_events/g_ticktime) < 1)
393*b47b5b34SRafael Vanoni 				g_ticktime = INTERVAL_DEFAULT;
394*b47b5b34SRafael Vanoni 			else
395*b47b5b34SRafael Vanoni 				g_ticktime = INTERVAL_UPDATE(last_time);
396*b47b5b34SRafael Vanoni 
397*b47b5b34SRafael Vanoni 		/*
398*b47b5b34SRafael Vanoni 		 * Restore user specified interval after a refresh
399*b47b5b34SRafael Vanoni 		 */
400*b47b5b34SRafael Vanoni 		if (keychar == 'R' && user_interval)
401*b47b5b34SRafael Vanoni 			g_ticktime = g_ticktime_usr;
402*b47b5b34SRafael Vanoni 	}
403*b47b5b34SRafael Vanoni 	return (EXIT_SUCCESS);
404*b47b5b34SRafael Vanoni }
405*b47b5b34SRafael Vanoni 
406*b47b5b34SRafael Vanoni void
407*b47b5b34SRafael Vanoni suggest_as_root(void)
408*b47b5b34SRafael Vanoni {
409*b47b5b34SRafael Vanoni 	add_suggestion("Suggestion: run as root to get suggestions"
410*b47b5b34SRafael Vanoni 	    " for reducing system power consumption",  40, NULL, NULL,
411*b47b5b34SRafael Vanoni 	    NULL);
412*b47b5b34SRafael Vanoni }
413