1bcde4861SRafael Vanoni Polanczyk /*
288681574SRafael Vanoni  * Copyright 2009, Intel Corporation
388681574SRafael Vanoni  * Copyright 2009, Sun Microsystems, Inc
4bcde4861SRafael Vanoni Polanczyk  *
5bcde4861SRafael Vanoni Polanczyk  * This file is part of PowerTOP
6bcde4861SRafael Vanoni Polanczyk  *
7bcde4861SRafael Vanoni Polanczyk  * This program file is free software; you can redistribute it and/or modify it
8bcde4861SRafael Vanoni Polanczyk  * under the terms of the GNU General Public License as published by the
9bcde4861SRafael Vanoni Polanczyk  * Free Software Foundation; version 2 of the License.
10bcde4861SRafael Vanoni Polanczyk  *
11bcde4861SRafael Vanoni Polanczyk  * This program is distributed in the hope that it will be useful, but WITHOUT
12bcde4861SRafael Vanoni Polanczyk  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13bcde4861SRafael Vanoni Polanczyk  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14bcde4861SRafael Vanoni Polanczyk  * for more details.
15bcde4861SRafael Vanoni Polanczyk  *
16bcde4861SRafael Vanoni Polanczyk  * You should have received a copy of the GNU General Public License
17bcde4861SRafael Vanoni Polanczyk  * along with this program in a file named COPYING; if not, write to the
18bcde4861SRafael Vanoni Polanczyk  * Free Software Foundation, Inc.,
19bcde4861SRafael Vanoni Polanczyk  * 51 Franklin Street, Fifth Floor,
20bcde4861SRafael Vanoni Polanczyk  * Boston, MA 02110-1301 USA
21bcde4861SRafael Vanoni Polanczyk  *
22bcde4861SRafael Vanoni Polanczyk  * Authors:
23bcde4861SRafael Vanoni Polanczyk  *	Arjan van de Ven <arjan@linux.intel.com>
24bcde4861SRafael Vanoni Polanczyk  *	Eric C Saxe <eric.saxe@sun.com>
25bcde4861SRafael Vanoni Polanczyk  *	Aubrey Li <aubrey.li@intel.com>
26bcde4861SRafael Vanoni Polanczyk  */
27bcde4861SRafael Vanoni Polanczyk 
28bcde4861SRafael Vanoni Polanczyk /*
29bcde4861SRafael Vanoni Polanczyk  * GPL Disclaimer
30bcde4861SRafael Vanoni Polanczyk  *
31bcde4861SRafael Vanoni Polanczyk  * For the avoidance of doubt, except that if any license choice other
32bcde4861SRafael Vanoni Polanczyk  * than GPL or LGPL is available it will apply instead, Sun elects to
33bcde4861SRafael Vanoni Polanczyk  * use only the General Public License version 2 (GPLv2) at this time
34bcde4861SRafael Vanoni Polanczyk  * for any software where a choice of GPL license versions is made
35bcde4861SRafael Vanoni Polanczyk  * available with the language indicating that GPLv2 or any later
36bcde4861SRafael Vanoni Polanczyk  * version may be used, or where a choice of which version of the GPL
37bcde4861SRafael Vanoni Polanczyk  * is applied is otherwise unspecified.
38bcde4861SRafael Vanoni Polanczyk  */
39bcde4861SRafael Vanoni Polanczyk 
40bcde4861SRafael Vanoni Polanczyk #include <getopt.h>
41bcde4861SRafael Vanoni Polanczyk #include <unistd.h>
42bcde4861SRafael Vanoni Polanczyk #include <stdio.h>
43bcde4861SRafael Vanoni Polanczyk #include <stdlib.h>
449bbf5ba1SRafael Vanoni #include <signal.h>
45bcde4861SRafael Vanoni Polanczyk #include <string.h>
46bcde4861SRafael Vanoni Polanczyk #include <ctype.h>
472d83778aSRafael Vanoni #include <poll.h>
48bcde4861SRafael Vanoni Polanczyk #include "powertop.h"
49bcde4861SRafael Vanoni Polanczyk 
50b47b5b34SRafael Vanoni /*
51b47b5b34SRafael Vanoni  * Global variables, see powertop.h for comments and extern declarations.
52b47b5b34SRafael Vanoni  * These are ordered by type, grouped by usage.
53b47b5b34SRafael Vanoni  */
54b47b5b34SRafael Vanoni int			g_bit_depth;
55*f795e601SToomas Soome int			g_total_events, g_top_events;
56b47b5b34SRafael Vanoni int			g_npstates, g_max_cstate, g_longest_cstate;
579bbf5ba1SRafael Vanoni uint_t			g_features;
58b47b5b34SRafael Vanoni uint_t			g_ncpus;
59b47b5b34SRafael Vanoni uint_t			g_ncpus_observed;
60b47b5b34SRafael Vanoni 
61*f795e601SToomas Soome processorid_t		*g_cpu_table;
62b47b5b34SRafael Vanoni 
632d83778aSRafael Vanoni double			g_interval_length;
64b47b5b34SRafael Vanoni hrtime_t		g_total_c_time;
65b47b5b34SRafael Vanoni 
66b47b5b34SRafael Vanoni uchar_t			g_op_mode;
67b47b5b34SRafael Vanoni boolean_t		g_gui;
68b47b5b34SRafael Vanoni uint_t			g_observed_cpu;
69b47b5b34SRafael Vanoni 
70*f795e601SToomas Soome event_info_t		g_event_info[EVENT_NUM_MAX];
71b47b5b34SRafael Vanoni state_info_t		g_cstate_info[NSTATES];
72b47b5b34SRafael Vanoni freq_state_info_t	g_pstate_info[NSTATES];
73b47b5b34SRafael Vanoni cpu_power_info_t	*g_cpu_power_states;
74b47b5b34SRafael Vanoni 
752d83778aSRafael Vanoni boolean_t		g_sig_resize;
76b47b5b34SRafael Vanoni 
77b47b5b34SRafael Vanoni uint_t			g_argc;
78b47b5b34SRafael Vanoni char			**g_argv;
79b47b5b34SRafael Vanoni 
80b47b5b34SRafael Vanoni static const int	true = 1;
81bcde4861SRafael Vanoni Polanczyk 
822d83778aSRafael Vanoni void
pt_sig_handler(int sig)832d83778aSRafael Vanoni pt_sig_handler(int sig)
842d83778aSRafael Vanoni {
852d83778aSRafael Vanoni 	switch (sig) {
862d83778aSRafael Vanoni 	case SIGWINCH:
872d83778aSRafael Vanoni 		g_sig_resize = B_TRUE;
882d83778aSRafael Vanoni 		break;
892d83778aSRafael Vanoni 	}
902d83778aSRafael Vanoni }
912d83778aSRafael Vanoni 
92bcde4861SRafael Vanoni Polanczyk int
main(int argc,char ** argv)93bcde4861SRafael Vanoni Polanczyk main(int argc, char **argv)
94bcde4861SRafael Vanoni Polanczyk {
952d83778aSRafael Vanoni 	double		interval, interval_usr;
96*f795e601SToomas Soome 	hrtime_t	interval_start;
972d83778aSRafael Vanoni 	int		index2 = 0, c, dump_count = 0;
982d83778aSRafael Vanoni 	char		*endptr, key;
999bbf5ba1SRafael Vanoni 	boolean_t	root_user = B_FALSE;
1002d83778aSRafael Vanoni 	struct pollfd	pollset;
101bcde4861SRafael Vanoni Polanczyk 
102bcde4861SRafael Vanoni Polanczyk 	static struct option opts[] = {
103bcde4861SRafael Vanoni Polanczyk 		{ "dump", 1, NULL, 'd' },
104bcde4861SRafael Vanoni Polanczyk 		{ "time", 1, NULL, 't' },
105bcde4861SRafael Vanoni Polanczyk 		{ "help", 0, NULL, 'h' },
106b47b5b34SRafael Vanoni 		{ "cpu", 1, NULL, 'c' },
107bcde4861SRafael Vanoni Polanczyk 		{ "verbose", 0, NULL, 'v' },
108bcde4861SRafael Vanoni Polanczyk 		{ 0, 0, NULL, 0 }
109bcde4861SRafael Vanoni Polanczyk 	};
110bcde4861SRafael Vanoni Polanczyk 
111bcde4861SRafael Vanoni Polanczyk 	pt_set_progname(argv[0]);
112bcde4861SRafael Vanoni Polanczyk 
113b47b5b34SRafael Vanoni 	/*
1149bbf5ba1SRafael Vanoni 	 * Enumerate the system's CPUs, populate cpu_table, g_ncpus
115b47b5b34SRafael Vanoni 	 */
1162d83778aSRafael Vanoni 	if ((g_ncpus = g_ncpus_observed = pt_enumerate_cpus()) == 0)
117bcde4861SRafael Vanoni Polanczyk 		exit(EXIT_FAILURE);
118bcde4861SRafael Vanoni Polanczyk 
1192d83778aSRafael Vanoni 	if ((g_bit_depth = pt_get_bit_depth()) < 0)
120b47b5b34SRafael Vanoni 		exit(EXIT_FAILURE);
121b47b5b34SRafael Vanoni 
1229bbf5ba1SRafael Vanoni 	g_features = 0;
1232d83778aSRafael Vanoni 	interval = interval_usr = INTERVAL_DEFAULT;
1249bbf5ba1SRafael Vanoni 	g_op_mode = PT_MODE_DEFAULT;
1259bbf5ba1SRafael Vanoni 	g_max_cstate = 0;
1269bbf5ba1SRafael Vanoni 	g_argv = NULL;
1279bbf5ba1SRafael Vanoni 	g_argc = 0;
1289bbf5ba1SRafael Vanoni 	g_observed_cpu = 0;
129e5bbdc06SRafael Vanoni 	g_turbo_supported = B_FALSE;
1302d83778aSRafael Vanoni 	g_sig_resize = B_FALSE;
1319bbf5ba1SRafael Vanoni 	g_curr_sugg = NULL;
132bcde4861SRafael Vanoni Polanczyk 
1332d83778aSRafael Vanoni 	while ((c = getopt_long(argc, argv, "d:t:hvc:", opts, &index2))
134b47b5b34SRafael Vanoni 	    != EOF) {
135bcde4861SRafael Vanoni Polanczyk 		if (c == -1)
136bcde4861SRafael Vanoni Polanczyk 			break;
137bcde4861SRafael Vanoni Polanczyk 
138bcde4861SRafael Vanoni Polanczyk 		switch (c) {
139bcde4861SRafael Vanoni Polanczyk 		case 'd':
1402d83778aSRafael Vanoni 			if (PT_ON_DUMP) {
1412d83778aSRafael Vanoni 				pt_usage();
1422d83778aSRafael Vanoni 				exit(EXIT_USAGE);
1432d83778aSRafael Vanoni 			}
144bcde4861SRafael Vanoni Polanczyk 
145636423dbSRafael Vanoni 			g_op_mode |= PT_MODE_DUMP;
1462d83778aSRafael Vanoni 			g_gui = B_FALSE;
147bcde4861SRafael Vanoni Polanczyk 			dump_count = (int)strtod(optarg, &endptr);
148bcde4861SRafael Vanoni Polanczyk 
149*f795e601SToomas Soome 			if (dump_count <= 0 || *endptr != '\0') {
1502d83778aSRafael Vanoni 				pt_usage();
151c77fd2f1SRafael Vanoni 				exit(EXIT_USAGE);
152c77fd2f1SRafael Vanoni 			}
153c77fd2f1SRafael Vanoni 
154bcde4861SRafael Vanoni Polanczyk 			break;
155bcde4861SRafael Vanoni Polanczyk 		case 't':
1562d83778aSRafael Vanoni 			if (PT_ON_TIME) {
1572d83778aSRafael Vanoni 				pt_usage();
1582d83778aSRafael Vanoni 				exit(EXIT_USAGE);
1592d83778aSRafael Vanoni 			}
160bcde4861SRafael Vanoni Polanczyk 
1612d83778aSRafael Vanoni 			g_op_mode |= PT_MODE_TIME;
1622d83778aSRafael Vanoni 			interval = interval_usr = (double)strtod(optarg,
163bcde4861SRafael Vanoni Polanczyk 			    &endptr);
164bcde4861SRafael Vanoni Polanczyk 
165*f795e601SToomas Soome 			if (*endptr != '\0' || interval < 1 ||
1662d83778aSRafael Vanoni 			    interval > INTERVAL_MAX) {
1672d83778aSRafael Vanoni 				pt_usage();
1682d83778aSRafael Vanoni 				exit(EXIT_USAGE);
1692d83778aSRafael Vanoni 			}
1702d83778aSRafael Vanoni 
171bcde4861SRafael Vanoni Polanczyk 			break;
172bcde4861SRafael Vanoni Polanczyk 		case 'v':
1732d83778aSRafael Vanoni 			if (PT_ON_CPU || PT_ON_VERBOSE) {
1742d83778aSRafael Vanoni 				pt_usage();
1752d83778aSRafael Vanoni 				exit(EXIT_USAGE);
1762d83778aSRafael Vanoni 			}
177bcde4861SRafael Vanoni Polanczyk 
178636423dbSRafael Vanoni 			g_op_mode |= PT_MODE_VERBOSE;
179b47b5b34SRafael Vanoni 			break;
180b47b5b34SRafael Vanoni 		case 'c':
1812d83778aSRafael Vanoni 			if (PT_ON_CPU || PT_ON_VERBOSE) {
1822d83778aSRafael Vanoni 				pt_usage();
1832d83778aSRafael Vanoni 				exit(EXIT_USAGE);
1842d83778aSRafael Vanoni 			}
185b47b5b34SRafael Vanoni 
186636423dbSRafael Vanoni 			g_op_mode |= PT_MODE_CPU;
187b47b5b34SRafael Vanoni 			g_observed_cpu = (uint_t)strtod(optarg, &endptr);
188b47b5b34SRafael Vanoni 
1892d83778aSRafael Vanoni 			if (g_observed_cpu >= g_ncpus) {
1902d83778aSRafael Vanoni 				pt_usage();
1912d83778aSRafael Vanoni 				exit(EXIT_USAGE);
1922d83778aSRafael Vanoni 			}
193b47b5b34SRafael Vanoni 
194b47b5b34SRafael Vanoni 			g_argc = 1;
195b47b5b34SRafael Vanoni 			g_ncpus_observed = 1;
196b47b5b34SRafael Vanoni 
197b47b5b34SRafael Vanoni 			if ((g_argv = malloc(sizeof (char *))) == NULL)
198b47b5b34SRafael Vanoni 				return (EXIT_FAILURE);
199b47b5b34SRafael Vanoni 
200b47b5b34SRafael Vanoni 			if ((*g_argv = malloc(sizeof (char) * 5)) == NULL)
201b47b5b34SRafael Vanoni 				return (EXIT_FAILURE);
202b47b5b34SRafael Vanoni 
203b47b5b34SRafael Vanoni 			(void) snprintf(*g_argv, 5, "%d\0", g_observed_cpu);
204bcde4861SRafael Vanoni Polanczyk 			break;
205bcde4861SRafael Vanoni Polanczyk 		case 'h':
2062d83778aSRafael Vanoni 			pt_usage();
2072d83778aSRafael Vanoni 			exit(EXIT_SUCCESS);
208bcde4861SRafael Vanoni Polanczyk 		default:
2092d83778aSRafael Vanoni 			pt_usage();
2102d83778aSRafael Vanoni 			exit(EXIT_USAGE);
211bcde4861SRafael Vanoni Polanczyk 		}
212bcde4861SRafael Vanoni Polanczyk 	}
213bcde4861SRafael Vanoni Polanczyk 
214c77fd2f1SRafael Vanoni 	if (optind < argc) {
2152d83778aSRafael Vanoni 		pt_usage();
216c77fd2f1SRafael Vanoni 		exit(EXIT_USAGE);
217c77fd2f1SRafael Vanoni 	}
218bcde4861SRafael Vanoni Polanczyk 
219b47b5b34SRafael Vanoni 	(void) printf("%s   %s\n\n", TITLE, COPYRIGHT_INTEL);
220bcde4861SRafael Vanoni Polanczyk 
2212d83778aSRafael Vanoni 	(void) printf("Collecting data for %.2f second(s) \n",
2222d83778aSRafael Vanoni 	    (float)interval);
2239bbf5ba1SRafael Vanoni 
2249bbf5ba1SRafael Vanoni 	/* Prepare P-state statistics */
2259bbf5ba1SRafael Vanoni 	if (pt_cpufreq_stat_prepare() == 0)
2269bbf5ba1SRafael Vanoni 		g_features |= FEATURE_PSTATE;
227bcde4861SRafael Vanoni Polanczyk 
228bcde4861SRafael Vanoni Polanczyk 	/* Prepare C-state statistics */
2292d83778aSRafael Vanoni 	if (pt_cpuidle_stat_prepare() == 0)
2309bbf5ba1SRafael Vanoni 		g_features |= FEATURE_CSTATE;
231bcde4861SRafael Vanoni Polanczyk 	else
232bcde4861SRafael Vanoni Polanczyk 		/*
233bcde4861SRafael Vanoni Polanczyk 		 * PowerTop was unable to run a DTrace program,
234bcde4861SRafael Vanoni Polanczyk 		 * most likely for lack of permissions.
235bcde4861SRafael Vanoni Polanczyk 		 */
236bcde4861SRafael Vanoni Polanczyk 		exit(EXIT_FAILURE);
237bcde4861SRafael Vanoni Polanczyk 
238bcde4861SRafael Vanoni Polanczyk 	/* Prepare event statistics */
239bcde4861SRafael Vanoni Polanczyk 	if (pt_events_stat_prepare() != -1)
2409bbf5ba1SRafael Vanoni 		g_features |= FEATURE_EVENTS;
241bcde4861SRafael Vanoni Polanczyk 
2429bbf5ba1SRafael Vanoni 	/*
2439bbf5ba1SRafael Vanoni 	 * If the system is running on battery, find out what's
2449bbf5ba1SRafael Vanoni 	 * the kstat module for it
2459bbf5ba1SRafael Vanoni 	 */
2462d83778aSRafael Vanoni 	pt_battery_mod_lookup();
247e5bbdc06SRafael Vanoni 
2489bbf5ba1SRafael Vanoni 	/* Prepare turbo statistics */
2499bbf5ba1SRafael Vanoni 	if (pt_turbo_stat_prepare() == 0)
2509bbf5ba1SRafael Vanoni 		g_features |= FEATURE_TURBO;
251bcde4861SRafael Vanoni Polanczyk 
2522d83778aSRafael Vanoni 	/*
2532d83778aSRafael Vanoni 	 * Initialize the display.
2542d83778aSRafael Vanoni 	 */
2552d83778aSRafael Vanoni 	if (!PT_ON_DUMP) {
2562d83778aSRafael Vanoni 		pt_display_init_curses();
2572d83778aSRafael Vanoni 		pt_display_setup(B_FALSE);
2582d83778aSRafael Vanoni 		(void) signal(SIGWINCH, pt_sig_handler);
2592d83778aSRafael Vanoni 
2602d83778aSRafael Vanoni 		pt_display_title_bar();
2612d83778aSRafael Vanoni 		pt_display_status_bar();
2622d83778aSRafael Vanoni 
2632d83778aSRafael Vanoni 		g_gui = B_TRUE;
2642d83778aSRafael Vanoni 		pollset.fd = STDIN_FILENO;
2652d83778aSRafael Vanoni 		pollset.events = POLLIN;
2662d83778aSRafael Vanoni 	}
2672d83778aSRafael Vanoni 
2689bbf5ba1SRafael Vanoni 	/*
2699bbf5ba1SRafael Vanoni 	 * Installs the initial suggestions, running as root and turning CPU
2709bbf5ba1SRafael Vanoni 	 * power management ON.
2719bbf5ba1SRafael Vanoni 	 */
2722d83778aSRafael Vanoni 	if (geteuid() != 0) {
2739bbf5ba1SRafael Vanoni 		pt_sugg_as_root();
2742d83778aSRafael Vanoni 	} else {
2759bbf5ba1SRafael Vanoni 		root_user = B_TRUE;
2769bbf5ba1SRafael Vanoni 		pt_cpufreq_suggest();
2779bbf5ba1SRafael Vanoni 	}
27888681574SRafael Vanoni 
279bcde4861SRafael Vanoni Polanczyk 	while (true) {
2802d83778aSRafael Vanoni 		key = 0;
281bcde4861SRafael Vanoni Polanczyk 
2822d83778aSRafael Vanoni 		if (g_sig_resize)
2832d83778aSRafael Vanoni 			pt_display_resize();
284bcde4861SRafael Vanoni Polanczyk 
2852d83778aSRafael Vanoni 		interval_start = gethrtime();
286bcde4861SRafael Vanoni Polanczyk 
2879bbf5ba1SRafael Vanoni 		if (!PT_ON_DUMP) {
2882d83778aSRafael Vanoni 			if (poll(&pollset, (nfds_t)1,
2892d83778aSRafael Vanoni 			    (int)(interval * MILLISEC)) > 0)
2902d83778aSRafael Vanoni 				(void) read(STDIN_FILENO, &key, 1);
2912d83778aSRafael Vanoni 		} else {
2922d83778aSRafael Vanoni 			(void) sleep((int)interval);
2932d83778aSRafael Vanoni 		}
294bcde4861SRafael Vanoni Polanczyk 
2952d83778aSRafael Vanoni 		g_interval_length = (double)(gethrtime() - interval_start)
2962d83778aSRafael Vanoni 		    /NANOSEC;
297bcde4861SRafael Vanoni Polanczyk 
2982d83778aSRafael Vanoni 		g_top_events = 0;
2992d83778aSRafael Vanoni 		g_total_events = 0;
300bcde4861SRafael Vanoni Polanczyk 
3019b37b909SRafael Vanoni 		(void) memset(g_event_info, 0,
3029b37b909SRafael Vanoni 		    EVENT_NUM_MAX * sizeof (event_info_t));
30392ad8f28SRafael Vanoni 		(void) memset(g_cstate_info, 0,
30492ad8f28SRafael Vanoni 		    NSTATES * sizeof (state_info_t));
305bcde4861SRafael Vanoni Polanczyk 
306bcde4861SRafael Vanoni Polanczyk 		/* Collect idle state transition stats */
3079bbf5ba1SRafael Vanoni 		if (g_features & FEATURE_CSTATE &&
3082d83778aSRafael Vanoni 		    pt_cpuidle_stat_collect(g_interval_length) < 0) {
309bcde4861SRafael Vanoni Polanczyk 			/* Reinitialize C-state statistics */
310bcde4861SRafael Vanoni Polanczyk 			if (pt_cpuidle_stat_prepare() != 0)
311bcde4861SRafael Vanoni Polanczyk 				exit(EXIT_FAILURE);
312bcde4861SRafael Vanoni Polanczyk 
3139bbf5ba1SRafael Vanoni 			continue;
314bcde4861SRafael Vanoni Polanczyk 		}
315bcde4861SRafael Vanoni Polanczyk 
316bcde4861SRafael Vanoni Polanczyk 		/* Collect frequency change stats */
3179bbf5ba1SRafael Vanoni 		if (g_features & FEATURE_PSTATE &&
3182d83778aSRafael Vanoni 		    pt_cpufreq_stat_collect(g_interval_length) < 0) {
319bcde4861SRafael Vanoni Polanczyk 			/* Reinitialize P-state statistics */
320bcde4861SRafael Vanoni Polanczyk 			if (pt_cpufreq_stat_prepare() != 0)
321bcde4861SRafael Vanoni Polanczyk 				exit(EXIT_FAILURE);
322bcde4861SRafael Vanoni Polanczyk 
3239bbf5ba1SRafael Vanoni 			continue;
324bcde4861SRafael Vanoni Polanczyk 		}
325bcde4861SRafael Vanoni Polanczyk 
326bcde4861SRafael Vanoni Polanczyk 		/* Collect event statistics */
3279bbf5ba1SRafael Vanoni 		if (g_features & FEATURE_EVENTS &&
328bcde4861SRafael Vanoni Polanczyk 		    pt_events_stat_collect() < 0) {
329bcde4861SRafael Vanoni Polanczyk 			/* Reinitialize event statistics */
330bcde4861SRafael Vanoni Polanczyk 			if (pt_events_stat_prepare() != 0)
331bcde4861SRafael Vanoni Polanczyk 				exit(EXIT_FAILURE);
332bcde4861SRafael Vanoni Polanczyk 
333bcde4861SRafael Vanoni Polanczyk 			continue;
3349bbf5ba1SRafael Vanoni 		}
335bcde4861SRafael Vanoni Polanczyk 
336e5bbdc06SRafael Vanoni 		/* Collect turbo statistics */
3379bbf5ba1SRafael Vanoni 		if (g_features & FEATURE_TURBO &&
3389bbf5ba1SRafael Vanoni 		    pt_turbo_stat_collect() < 0)
339e5bbdc06SRafael Vanoni 			exit(EXIT_FAILURE);
340bcde4861SRafael Vanoni Polanczyk 
341bcde4861SRafael Vanoni Polanczyk 		/* Show CPU power states */
3429bbf5ba1SRafael Vanoni 		pt_display_states();
343bcde4861SRafael Vanoni Polanczyk 
344bcde4861SRafael Vanoni Polanczyk 		/* Show wakeups events affecting PM */
3459bbf5ba1SRafael Vanoni 		if (g_features & FEATURE_EVENTS) {
3462d83778aSRafael Vanoni 			pt_display_wakeups(g_interval_length);
3472d83778aSRafael Vanoni 			pt_display_events(g_interval_length);
348bcde4861SRafael Vanoni Polanczyk 		}
349bcde4861SRafael Vanoni Polanczyk 
3509bbf5ba1SRafael Vanoni 		pt_battery_print();
351bcde4861SRafael Vanoni Polanczyk 
352636423dbSRafael Vanoni 		if (key && !PT_ON_DUMP) {
3532d83778aSRafael Vanoni 			switch (toupper(key)) {
354bcde4861SRafael Vanoni Polanczyk 			case 'Q':
355bcde4861SRafael Vanoni Polanczyk 				exit(EXIT_SUCCESS);
356bcde4861SRafael Vanoni Polanczyk 				break;
3579bbf5ba1SRafael Vanoni 
358bcde4861SRafael Vanoni Polanczyk 			case 'R':
3592d83778aSRafael Vanoni 				interval = 3;
360bcde4861SRafael Vanoni Polanczyk 				break;
361bcde4861SRafael Vanoni Polanczyk 			}
362bcde4861SRafael Vanoni Polanczyk 
3639bbf5ba1SRafael Vanoni 			/*
3649bbf5ba1SRafael Vanoni 			 * Check if the user has activated the current
3659bbf5ba1SRafael Vanoni 			 * suggestion.
3669bbf5ba1SRafael Vanoni 			 */
3679bbf5ba1SRafael Vanoni 			if (g_curr_sugg != NULL &&
3682d83778aSRafael Vanoni 			    toupper(key) == g_curr_sugg->key &&
3692d83778aSRafael Vanoni 			    g_curr_sugg->func)
3709bbf5ba1SRafael Vanoni 				g_curr_sugg->func();
371bcde4861SRafael Vanoni Polanczyk 		}
372bcde4861SRafael Vanoni Polanczyk 
373bcde4861SRafael Vanoni Polanczyk 		if (dump_count)
374bcde4861SRafael Vanoni Polanczyk 			dump_count--;
375bcde4861SRafael Vanoni Polanczyk 
376bcde4861SRafael Vanoni Polanczyk 		/* Exits if user requested a dump */
3779bbf5ba1SRafael Vanoni 		if (PT_ON_DUMP && !dump_count)
378bcde4861SRafael Vanoni Polanczyk 			exit(EXIT_SUCCESS);
379bcde4861SRafael Vanoni Polanczyk 
380bcde4861SRafael Vanoni Polanczyk 		/* No key pressed, will suggest something */
381bcde4861SRafael Vanoni Polanczyk 		if (!key && !dump_count)
3829bbf5ba1SRafael Vanoni 			pt_sugg_pick();
383bcde4861SRafael Vanoni Polanczyk 
384bcde4861SRafael Vanoni Polanczyk 		/* Refresh display */
3859bbf5ba1SRafael Vanoni 		if (!PT_ON_DUMP)
3869bbf5ba1SRafael Vanoni 			pt_display_update();
3879bbf5ba1SRafael Vanoni 
3889bbf5ba1SRafael Vanoni 		if (root_user)
3899bbf5ba1SRafael Vanoni 			pt_cpufreq_suggest();
390bcde4861SRafael Vanoni Polanczyk 
391bcde4861SRafael Vanoni Polanczyk 		/*
392bcde4861SRafael Vanoni Polanczyk 		 * Update the interval based on how long the CPU was in the
393bcde4861SRafael Vanoni Polanczyk 		 * longest c-state during the last snapshot. If the user
394bcde4861SRafael Vanoni Polanczyk 		 * specified an interval we skip this bit and keep it fixed.
395bcde4861SRafael Vanoni Polanczyk 		 */
3962d83778aSRafael Vanoni 		if (g_features & FEATURE_CSTATE && !PT_ON_TIME &&
397b54d0971SMilan Jurik 		    g_longest_cstate > 0 &&
398b54d0971SMilan Jurik 		    g_cstate_info[g_longest_cstate].events > 0) {
3992d83778aSRafael Vanoni 			double deep_idle_res = (((double)
4009bbf5ba1SRafael Vanoni 			    g_cstate_info[g_longest_cstate].total_time/MICROSEC
4019bbf5ba1SRafael Vanoni 			    /g_ncpus)/g_cstate_info[g_longest_cstate].events);
402bcde4861SRafael Vanoni Polanczyk 
4032d83778aSRafael Vanoni 			if (deep_idle_res < INTERVAL_DEFAULT ||
4042d83778aSRafael Vanoni 			    (g_total_events/interval) < 1)
4052d83778aSRafael Vanoni 				interval = INTERVAL_DEFAULT;
406bcde4861SRafael Vanoni Polanczyk 			else
4072d83778aSRafael Vanoni 				interval = INTERVAL_UPDATE(deep_idle_res);
4089bbf5ba1SRafael Vanoni 		} else {
4099bbf5ba1SRafael Vanoni 			/*
4109bbf5ba1SRafael Vanoni 			 * Restore interval after a refresh.
4119bbf5ba1SRafael Vanoni 			 */
4129bbf5ba1SRafael Vanoni 			if (key)
4132d83778aSRafael Vanoni 				interval = interval_usr;
4149bbf5ba1SRafael Vanoni 		}
415bcde4861SRafael Vanoni Polanczyk 	}
416bcde4861SRafael Vanoni Polanczyk 
4179bbf5ba1SRafael Vanoni 	return (EXIT_SUCCESS);
418bcde4861SRafael Vanoni Polanczyk }
419