xref: /onnv-gate/usr/src/cmd/powertop/common/powertop.c (revision 11555:04cf79226bed)
19338Srafael.vanoni@sun.com /*
29338Srafael.vanoni@sun.com  * Copyright 2009, Intel Corporation
39338Srafael.vanoni@sun.com  * Copyright 2009, Sun Microsystems, Inc
49338Srafael.vanoni@sun.com  *
59338Srafael.vanoni@sun.com  * This file is part of PowerTOP
69338Srafael.vanoni@sun.com  *
79338Srafael.vanoni@sun.com  * This program file is free software; you can redistribute it and/or modify it
89338Srafael.vanoni@sun.com  * under the terms of the GNU General Public License as published by the
99338Srafael.vanoni@sun.com  * Free Software Foundation; version 2 of the License.
109338Srafael.vanoni@sun.com  *
119338Srafael.vanoni@sun.com  * This program is distributed in the hope that it will be useful, but WITHOUT
129338Srafael.vanoni@sun.com  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
139338Srafael.vanoni@sun.com  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
149338Srafael.vanoni@sun.com  * for more details.
159338Srafael.vanoni@sun.com  *
169338Srafael.vanoni@sun.com  * You should have received a copy of the GNU General Public License
179338Srafael.vanoni@sun.com  * along with this program in a file named COPYING; if not, write to the
189338Srafael.vanoni@sun.com  * Free Software Foundation, Inc.,
199338Srafael.vanoni@sun.com  * 51 Franklin Street, Fifth Floor,
209338Srafael.vanoni@sun.com  * Boston, MA 02110-1301 USA
219338Srafael.vanoni@sun.com  *
229338Srafael.vanoni@sun.com  * Authors:
239338Srafael.vanoni@sun.com  *	Arjan van de Ven <arjan@linux.intel.com>
249338Srafael.vanoni@sun.com  *	Eric C Saxe <eric.saxe@sun.com>
259338Srafael.vanoni@sun.com  *	Aubrey Li <aubrey.li@intel.com>
269338Srafael.vanoni@sun.com  */
279338Srafael.vanoni@sun.com 
289338Srafael.vanoni@sun.com /*
299338Srafael.vanoni@sun.com  * GPL Disclaimer
309338Srafael.vanoni@sun.com  *
319338Srafael.vanoni@sun.com  * For the avoidance of doubt, except that if any license choice other
329338Srafael.vanoni@sun.com  * than GPL or LGPL is available it will apply instead, Sun elects to
339338Srafael.vanoni@sun.com  * use only the General Public License version 2 (GPLv2) at this time
349338Srafael.vanoni@sun.com  * for any software where a choice of GPL license versions is made
359338Srafael.vanoni@sun.com  * available with the language indicating that GPLv2 or any later
369338Srafael.vanoni@sun.com  * version may be used, or where a choice of which version of the GPL
379338Srafael.vanoni@sun.com  * is applied is otherwise unspecified.
389338Srafael.vanoni@sun.com  */
399338Srafael.vanoni@sun.com 
409338Srafael.vanoni@sun.com #include <getopt.h>
419338Srafael.vanoni@sun.com #include <unistd.h>
429338Srafael.vanoni@sun.com #include <stdio.h>
439338Srafael.vanoni@sun.com #include <stdlib.h>
449908Srafael.vanoni@sun.com #include <signal.h>
459338Srafael.vanoni@sun.com #include <string.h>
469338Srafael.vanoni@sun.com #include <ctype.h>
4711122Srafael.vanoni@sun.com #include <poll.h>
489338Srafael.vanoni@sun.com #include "powertop.h"
499338Srafael.vanoni@sun.com 
509338Srafael.vanoni@sun.com /*
519338Srafael.vanoni@sun.com  * Global variables, see powertop.h for comments and extern declarations.
529338Srafael.vanoni@sun.com  * These are ordered by type, grouped by usage.
539338Srafael.vanoni@sun.com  */
549338Srafael.vanoni@sun.com int			g_bit_depth;
559711Srafael.vanoni@sun.com int 			g_total_events, g_top_events;
569338Srafael.vanoni@sun.com int			g_npstates, g_max_cstate, g_longest_cstate;
579908Srafael.vanoni@sun.com uint_t			g_features;
589338Srafael.vanoni@sun.com uint_t			g_ncpus;
599338Srafael.vanoni@sun.com uint_t			g_ncpus_observed;
609338Srafael.vanoni@sun.com 
619338Srafael.vanoni@sun.com processorid_t 		*g_cpu_table;
629338Srafael.vanoni@sun.com 
6311122Srafael.vanoni@sun.com double			g_interval_length;
649338Srafael.vanoni@sun.com hrtime_t		g_total_c_time;
659338Srafael.vanoni@sun.com 
669338Srafael.vanoni@sun.com uchar_t			g_op_mode;
679338Srafael.vanoni@sun.com boolean_t		g_gui;
689338Srafael.vanoni@sun.com uint_t			g_observed_cpu;
699338Srafael.vanoni@sun.com 
709338Srafael.vanoni@sun.com event_info_t    	g_event_info[EVENT_NUM_MAX];
719338Srafael.vanoni@sun.com state_info_t		g_cstate_info[NSTATES];
729338Srafael.vanoni@sun.com freq_state_info_t	g_pstate_info[NSTATES];
739338Srafael.vanoni@sun.com cpu_power_info_t	*g_cpu_power_states;
749338Srafael.vanoni@sun.com 
759338Srafael.vanoni@sun.com boolean_t		g_turbo_supported;
7611122Srafael.vanoni@sun.com boolean_t		g_sig_resize;
779338Srafael.vanoni@sun.com 
789338Srafael.vanoni@sun.com uint_t			g_argc;
799338Srafael.vanoni@sun.com char			**g_argv;
809338Srafael.vanoni@sun.com 
819338Srafael.vanoni@sun.com char			*optarg;
829338Srafael.vanoni@sun.com 
839338Srafael.vanoni@sun.com static const int	true = 1;
849338Srafael.vanoni@sun.com 
8511122Srafael.vanoni@sun.com void
pt_sig_handler(int sig)8611122Srafael.vanoni@sun.com pt_sig_handler(int sig)
8711122Srafael.vanoni@sun.com {
8811122Srafael.vanoni@sun.com 	switch (sig) {
8911122Srafael.vanoni@sun.com 	case SIGWINCH:
9011122Srafael.vanoni@sun.com 		g_sig_resize = B_TRUE;
9111122Srafael.vanoni@sun.com 		break;
9211122Srafael.vanoni@sun.com 	}
9311122Srafael.vanoni@sun.com }
9411122Srafael.vanoni@sun.com 
959338Srafael.vanoni@sun.com int
main(int argc,char ** argv)969338Srafael.vanoni@sun.com main(int argc, char **argv)
979338Srafael.vanoni@sun.com {
9811122Srafael.vanoni@sun.com 	double		interval, interval_usr;
9911122Srafael.vanoni@sun.com 	hrtime_t 	interval_start;
10011122Srafael.vanoni@sun.com 	int		index2 = 0, c, dump_count = 0;
10111122Srafael.vanoni@sun.com 	char		*endptr, key;
1029908Srafael.vanoni@sun.com 	boolean_t	root_user = B_FALSE;
10311122Srafael.vanoni@sun.com 	struct pollfd	pollset;
1049338Srafael.vanoni@sun.com 
1059338Srafael.vanoni@sun.com 	static struct option opts[] = {
1069338Srafael.vanoni@sun.com 		{ "dump", 1, NULL, 'd' },
1079338Srafael.vanoni@sun.com 		{ "time", 1, NULL, 't' },
1089338Srafael.vanoni@sun.com 		{ "help", 0, NULL, 'h' },
1099338Srafael.vanoni@sun.com 		{ "cpu", 1, NULL, 'c' },
1109338Srafael.vanoni@sun.com 		{ "verbose", 0, NULL, 'v' },
1119338Srafael.vanoni@sun.com 		{ 0, 0, NULL, 0 }
1129338Srafael.vanoni@sun.com 	};
1139338Srafael.vanoni@sun.com 
1149338Srafael.vanoni@sun.com 	pt_set_progname(argv[0]);
1159338Srafael.vanoni@sun.com 
1169338Srafael.vanoni@sun.com 	/*
1179908Srafael.vanoni@sun.com 	 * Enumerate the system's CPUs, populate cpu_table, g_ncpus
1189338Srafael.vanoni@sun.com 	 */
11911122Srafael.vanoni@sun.com 	if ((g_ncpus = g_ncpus_observed = pt_enumerate_cpus()) == 0)
1209338Srafael.vanoni@sun.com 		exit(EXIT_FAILURE);
1219338Srafael.vanoni@sun.com 
12211122Srafael.vanoni@sun.com 	if ((g_bit_depth = pt_get_bit_depth()) < 0)
1239338Srafael.vanoni@sun.com 		exit(EXIT_FAILURE);
1249338Srafael.vanoni@sun.com 
1259908Srafael.vanoni@sun.com 	g_features = 0;
12611122Srafael.vanoni@sun.com 	interval = interval_usr = INTERVAL_DEFAULT;
1279908Srafael.vanoni@sun.com 	g_op_mode = PT_MODE_DEFAULT;
1289908Srafael.vanoni@sun.com 	g_max_cstate = 0;
1299908Srafael.vanoni@sun.com 	g_argv = NULL;
1309908Srafael.vanoni@sun.com 	g_argc = 0;
1319908Srafael.vanoni@sun.com 	g_observed_cpu = 0;
1329338Srafael.vanoni@sun.com 	g_turbo_supported = B_FALSE;
13311122Srafael.vanoni@sun.com 	g_sig_resize = B_FALSE;
1349908Srafael.vanoni@sun.com 	g_curr_sugg = NULL;
1359338Srafael.vanoni@sun.com 
13611122Srafael.vanoni@sun.com 	while ((c = getopt_long(argc, argv, "d:t:hvc:", opts, &index2))
1379338Srafael.vanoni@sun.com 	    != EOF) {
1389338Srafael.vanoni@sun.com 		if (c == -1)
1399338Srafael.vanoni@sun.com 			break;
1409338Srafael.vanoni@sun.com 
1419338Srafael.vanoni@sun.com 		switch (c) {
1429338Srafael.vanoni@sun.com 		case 'd':
14311122Srafael.vanoni@sun.com 			if (PT_ON_DUMP) {
14411122Srafael.vanoni@sun.com 				pt_usage();
14511122Srafael.vanoni@sun.com 				exit(EXIT_USAGE);
14611122Srafael.vanoni@sun.com 			}
1479338Srafael.vanoni@sun.com 
1489711Srafael.vanoni@sun.com 			g_op_mode |= PT_MODE_DUMP;
14911122Srafael.vanoni@sun.com 			g_gui = B_FALSE;
1509338Srafael.vanoni@sun.com 			dump_count = (int)strtod(optarg, &endptr);
1519338Srafael.vanoni@sun.com 
152*11555Srafael.vanoni@sun.com 			if (dump_count <= 0 || *endptr != NULL) {
15311122Srafael.vanoni@sun.com 				pt_usage();
154*11555Srafael.vanoni@sun.com 				exit(EXIT_USAGE);
155*11555Srafael.vanoni@sun.com 			}
156*11555Srafael.vanoni@sun.com 
1579338Srafael.vanoni@sun.com 			break;
1589338Srafael.vanoni@sun.com 		case 't':
15911122Srafael.vanoni@sun.com 			if (PT_ON_TIME) {
16011122Srafael.vanoni@sun.com 				pt_usage();
16111122Srafael.vanoni@sun.com 				exit(EXIT_USAGE);
16211122Srafael.vanoni@sun.com 			}
1639338Srafael.vanoni@sun.com 
16411122Srafael.vanoni@sun.com 			g_op_mode |= PT_MODE_TIME;
16511122Srafael.vanoni@sun.com 			interval = interval_usr = (double)strtod(optarg,
1669338Srafael.vanoni@sun.com 			    &endptr);
1679338Srafael.vanoni@sun.com 
16811122Srafael.vanoni@sun.com 			if (*endptr != NULL || interval < 1 ||
16911122Srafael.vanoni@sun.com 			    interval > INTERVAL_MAX) {
17011122Srafael.vanoni@sun.com 				pt_usage();
17111122Srafael.vanoni@sun.com 				exit(EXIT_USAGE);
17211122Srafael.vanoni@sun.com 			}
17311122Srafael.vanoni@sun.com 
1749338Srafael.vanoni@sun.com 			break;
1759338Srafael.vanoni@sun.com 		case 'v':
17611122Srafael.vanoni@sun.com 			if (PT_ON_CPU || PT_ON_VERBOSE) {
17711122Srafael.vanoni@sun.com 				pt_usage();
17811122Srafael.vanoni@sun.com 				exit(EXIT_USAGE);
17911122Srafael.vanoni@sun.com 			}
1809338Srafael.vanoni@sun.com 
1819711Srafael.vanoni@sun.com 			g_op_mode |= PT_MODE_VERBOSE;
1829338Srafael.vanoni@sun.com 			break;
1839338Srafael.vanoni@sun.com 		case 'c':
18411122Srafael.vanoni@sun.com 			if (PT_ON_CPU || PT_ON_VERBOSE) {
18511122Srafael.vanoni@sun.com 				pt_usage();
18611122Srafael.vanoni@sun.com 				exit(EXIT_USAGE);
18711122Srafael.vanoni@sun.com 			}
1889338Srafael.vanoni@sun.com 
1899711Srafael.vanoni@sun.com 			g_op_mode |= PT_MODE_CPU;
1909338Srafael.vanoni@sun.com 			g_observed_cpu = (uint_t)strtod(optarg, &endptr);
1919338Srafael.vanoni@sun.com 
19211122Srafael.vanoni@sun.com 			if (g_observed_cpu >= g_ncpus) {
19311122Srafael.vanoni@sun.com 				pt_usage();
19411122Srafael.vanoni@sun.com 				exit(EXIT_USAGE);
19511122Srafael.vanoni@sun.com 			}
1969338Srafael.vanoni@sun.com 
1979338Srafael.vanoni@sun.com 			g_argc = 1;
1989338Srafael.vanoni@sun.com 			g_ncpus_observed = 1;
1999338Srafael.vanoni@sun.com 
2009338Srafael.vanoni@sun.com 			if ((g_argv = malloc(sizeof (char *))) == NULL)
2019338Srafael.vanoni@sun.com 				return (EXIT_FAILURE);
2029338Srafael.vanoni@sun.com 
2039338Srafael.vanoni@sun.com 			if ((*g_argv = malloc(sizeof (char) * 5)) == NULL)
2049338Srafael.vanoni@sun.com 				return (EXIT_FAILURE);
2059338Srafael.vanoni@sun.com 
2069338Srafael.vanoni@sun.com 			(void) snprintf(*g_argv, 5, "%d\0", g_observed_cpu);
2079338Srafael.vanoni@sun.com 			break;
2089338Srafael.vanoni@sun.com 		case 'h':
20911122Srafael.vanoni@sun.com 			pt_usage();
21011122Srafael.vanoni@sun.com 			exit(EXIT_SUCCESS);
2119338Srafael.vanoni@sun.com 		default:
21211122Srafael.vanoni@sun.com 			pt_usage();
21311122Srafael.vanoni@sun.com 			exit(EXIT_USAGE);
2149338Srafael.vanoni@sun.com 		}
2159338Srafael.vanoni@sun.com 	}
2169338Srafael.vanoni@sun.com 
217*11555Srafael.vanoni@sun.com 	if (optind < argc) {
21811122Srafael.vanoni@sun.com 		pt_usage();
219*11555Srafael.vanoni@sun.com 		exit(EXIT_USAGE);
220*11555Srafael.vanoni@sun.com 	}
2219338Srafael.vanoni@sun.com 
2229338Srafael.vanoni@sun.com 	(void) printf("%s   %s\n\n", TITLE, COPYRIGHT_INTEL);
2239338Srafael.vanoni@sun.com 
22411122Srafael.vanoni@sun.com 	(void) printf("Collecting data for %.2f second(s) \n",
22511122Srafael.vanoni@sun.com 	    (float)interval);
2269908Srafael.vanoni@sun.com 
2279908Srafael.vanoni@sun.com 	/* Prepare P-state statistics */
2289908Srafael.vanoni@sun.com 	if (pt_cpufreq_stat_prepare() == 0)
2299908Srafael.vanoni@sun.com 		g_features |= FEATURE_PSTATE;
2309338Srafael.vanoni@sun.com 
2319338Srafael.vanoni@sun.com 	/* Prepare C-state statistics */
23211122Srafael.vanoni@sun.com 	if (pt_cpuidle_stat_prepare() == 0)
2339908Srafael.vanoni@sun.com 		g_features |= FEATURE_CSTATE;
2349338Srafael.vanoni@sun.com 	else
2359338Srafael.vanoni@sun.com 		/*
2369338Srafael.vanoni@sun.com 		 * PowerTop was unable to run a DTrace program,
2379338Srafael.vanoni@sun.com 		 * most likely for lack of permissions.
2389338Srafael.vanoni@sun.com 		 */
2399338Srafael.vanoni@sun.com 		exit(EXIT_FAILURE);
2409338Srafael.vanoni@sun.com 
2419338Srafael.vanoni@sun.com 	/* Prepare event statistics */
2429338Srafael.vanoni@sun.com 	if (pt_events_stat_prepare() != -1)
2439908Srafael.vanoni@sun.com 		g_features |= FEATURE_EVENTS;
2449908Srafael.vanoni@sun.com 
2459908Srafael.vanoni@sun.com 	/*
2469908Srafael.vanoni@sun.com 	 * If the system is running on battery, find out what's
2479908Srafael.vanoni@sun.com 	 * the kstat module for it
2489908Srafael.vanoni@sun.com 	 */
24911122Srafael.vanoni@sun.com 	pt_battery_mod_lookup();
2509338Srafael.vanoni@sun.com 
2519338Srafael.vanoni@sun.com 	/* Prepare turbo statistics */
2529908Srafael.vanoni@sun.com 	if (pt_turbo_stat_prepare() == 0)
2539908Srafael.vanoni@sun.com 		g_features |= FEATURE_TURBO;
2549338Srafael.vanoni@sun.com 
2559908Srafael.vanoni@sun.com 	/*
25611122Srafael.vanoni@sun.com 	 * Initialize the display.
25711122Srafael.vanoni@sun.com 	 */
25811122Srafael.vanoni@sun.com 	if (!PT_ON_DUMP) {
25911122Srafael.vanoni@sun.com 		pt_display_init_curses();
26011122Srafael.vanoni@sun.com 		pt_display_setup(B_FALSE);
26111122Srafael.vanoni@sun.com 		(void) signal(SIGWINCH, pt_sig_handler);
26211122Srafael.vanoni@sun.com 
26311122Srafael.vanoni@sun.com 		pt_display_title_bar();
26411122Srafael.vanoni@sun.com 		pt_display_status_bar();
26511122Srafael.vanoni@sun.com 
26611122Srafael.vanoni@sun.com 		g_gui = B_TRUE;
26711122Srafael.vanoni@sun.com 		pollset.fd = STDIN_FILENO;
26811122Srafael.vanoni@sun.com 		pollset.events = POLLIN;
26911122Srafael.vanoni@sun.com 	}
27011122Srafael.vanoni@sun.com 
27111122Srafael.vanoni@sun.com 	/*
2729908Srafael.vanoni@sun.com 	 * Installs the initial suggestions, running as root and turning CPU
2739908Srafael.vanoni@sun.com 	 * power management ON.
2749908Srafael.vanoni@sun.com 	 */
27511122Srafael.vanoni@sun.com 	if (geteuid() != 0) {
2769908Srafael.vanoni@sun.com 		pt_sugg_as_root();
27711122Srafael.vanoni@sun.com 	} else {
2789908Srafael.vanoni@sun.com 		root_user = B_TRUE;
2799908Srafael.vanoni@sun.com 		pt_cpufreq_suggest();
2809908Srafael.vanoni@sun.com 	}
2819338Srafael.vanoni@sun.com 
2829338Srafael.vanoni@sun.com 	while (true) {
28311122Srafael.vanoni@sun.com 		key = 0;
2849338Srafael.vanoni@sun.com 
28511122Srafael.vanoni@sun.com 		if (g_sig_resize)
28611122Srafael.vanoni@sun.com 			pt_display_resize();
2879338Srafael.vanoni@sun.com 
28811122Srafael.vanoni@sun.com 		interval_start = gethrtime();
2899338Srafael.vanoni@sun.com 
2909908Srafael.vanoni@sun.com 		if (!PT_ON_DUMP) {
29111122Srafael.vanoni@sun.com 			if (poll(&pollset, (nfds_t)1,
29211122Srafael.vanoni@sun.com 			    (int)(interval * MILLISEC)) > 0)
29311122Srafael.vanoni@sun.com 				(void) read(STDIN_FILENO, &key, 1);
29411122Srafael.vanoni@sun.com 		} else {
29511122Srafael.vanoni@sun.com 			(void) sleep((int)interval);
29611122Srafael.vanoni@sun.com 		}
2979338Srafael.vanoni@sun.com 
29811122Srafael.vanoni@sun.com 		g_interval_length = (double)(gethrtime() - interval_start)
29911122Srafael.vanoni@sun.com 		    /NANOSEC;
3009338Srafael.vanoni@sun.com 
30111122Srafael.vanoni@sun.com 		g_top_events = 0;
30211122Srafael.vanoni@sun.com 		g_total_events = 0;
3039338Srafael.vanoni@sun.com 
3049346Srafael.vanoni@sun.com 		(void) memset(g_event_info, 0,
3059346Srafael.vanoni@sun.com 		    EVENT_NUM_MAX * sizeof (event_info_t));
3069383Srafael.vanoni@sun.com 		(void) memset(g_cstate_info, 0,
3079383Srafael.vanoni@sun.com 		    NSTATES * sizeof (state_info_t));
3089338Srafael.vanoni@sun.com 
3099338Srafael.vanoni@sun.com 		/* Collect idle state transition stats */
3109908Srafael.vanoni@sun.com 		if (g_features & FEATURE_CSTATE &&
31111122Srafael.vanoni@sun.com 		    pt_cpuidle_stat_collect(g_interval_length) < 0) {
3129338Srafael.vanoni@sun.com 			/* Reinitialize C-state statistics */
3139338Srafael.vanoni@sun.com 			if (pt_cpuidle_stat_prepare() != 0)
3149338Srafael.vanoni@sun.com 				exit(EXIT_FAILURE);
3159338Srafael.vanoni@sun.com 
3169908Srafael.vanoni@sun.com 			continue;
3179338Srafael.vanoni@sun.com 		}
3189338Srafael.vanoni@sun.com 
3199338Srafael.vanoni@sun.com 		/* Collect frequency change stats */
3209908Srafael.vanoni@sun.com 		if (g_features & FEATURE_PSTATE &&
32111122Srafael.vanoni@sun.com 		    pt_cpufreq_stat_collect(g_interval_length) < 0) {
3229338Srafael.vanoni@sun.com 			/* Reinitialize P-state statistics */
3239338Srafael.vanoni@sun.com 			if (pt_cpufreq_stat_prepare() != 0)
3249338Srafael.vanoni@sun.com 				exit(EXIT_FAILURE);
3259338Srafael.vanoni@sun.com 
3269908Srafael.vanoni@sun.com 			continue;
3279338Srafael.vanoni@sun.com 		}
3289338Srafael.vanoni@sun.com 
3299338Srafael.vanoni@sun.com 		/* Collect event statistics */
3309908Srafael.vanoni@sun.com 		if (g_features & FEATURE_EVENTS &&
3319338Srafael.vanoni@sun.com 		    pt_events_stat_collect() < 0) {
3329338Srafael.vanoni@sun.com 			/* Reinitialize event statistics */
3339338Srafael.vanoni@sun.com 			if (pt_events_stat_prepare() != 0)
3349338Srafael.vanoni@sun.com 				exit(EXIT_FAILURE);
3359338Srafael.vanoni@sun.com 
3369338Srafael.vanoni@sun.com 			continue;
3379338Srafael.vanoni@sun.com 		}
3389338Srafael.vanoni@sun.com 
3399908Srafael.vanoni@sun.com 		/* Collect turbo statistics */
3409908Srafael.vanoni@sun.com 		if (g_features & FEATURE_TURBO &&
3419908Srafael.vanoni@sun.com 		    pt_turbo_stat_collect() < 0)
3429908Srafael.vanoni@sun.com 			exit(EXIT_FAILURE);
3439908Srafael.vanoni@sun.com 
3449908Srafael.vanoni@sun.com 		/* Show CPU power states */
3459908Srafael.vanoni@sun.com 		pt_display_states();
3469908Srafael.vanoni@sun.com 
3479908Srafael.vanoni@sun.com 		/* Show wakeups events affecting PM */
3489908Srafael.vanoni@sun.com 		if (g_features & FEATURE_EVENTS) {
34911122Srafael.vanoni@sun.com 			pt_display_wakeups(g_interval_length);
35011122Srafael.vanoni@sun.com 			pt_display_events(g_interval_length);
3519338Srafael.vanoni@sun.com 		}
3529338Srafael.vanoni@sun.com 
3539908Srafael.vanoni@sun.com 		pt_battery_print();
3549338Srafael.vanoni@sun.com 
3559711Srafael.vanoni@sun.com 		if (key && !PT_ON_DUMP) {
35611122Srafael.vanoni@sun.com 			switch (toupper(key)) {
3579338Srafael.vanoni@sun.com 			case 'Q':
3589338Srafael.vanoni@sun.com 				exit(EXIT_SUCCESS);
3599338Srafael.vanoni@sun.com 				break;
3609908Srafael.vanoni@sun.com 
3619338Srafael.vanoni@sun.com 			case 'R':
36211122Srafael.vanoni@sun.com 				interval = 3;
3639338Srafael.vanoni@sun.com 				break;
3649338Srafael.vanoni@sun.com 			}
3659338Srafael.vanoni@sun.com 
3669908Srafael.vanoni@sun.com 			/*
3679908Srafael.vanoni@sun.com 			 * Check if the user has activated the current
3689908Srafael.vanoni@sun.com 			 * suggestion.
3699908Srafael.vanoni@sun.com 			 */
3709908Srafael.vanoni@sun.com 			if (g_curr_sugg != NULL &&
37111122Srafael.vanoni@sun.com 			    toupper(key) == g_curr_sugg->key &&
37211122Srafael.vanoni@sun.com 			    g_curr_sugg->func)
3739908Srafael.vanoni@sun.com 				g_curr_sugg->func();
3749338Srafael.vanoni@sun.com 		}
3759338Srafael.vanoni@sun.com 
3769338Srafael.vanoni@sun.com 		if (dump_count)
3779338Srafael.vanoni@sun.com 			dump_count--;
3789338Srafael.vanoni@sun.com 
3799338Srafael.vanoni@sun.com 		/* Exits if user requested a dump */
3809908Srafael.vanoni@sun.com 		if (PT_ON_DUMP && !dump_count)
3819338Srafael.vanoni@sun.com 			exit(EXIT_SUCCESS);
3829338Srafael.vanoni@sun.com 
3839338Srafael.vanoni@sun.com 		/* No key pressed, will suggest something */
3849338Srafael.vanoni@sun.com 		if (!key && !dump_count)
3859908Srafael.vanoni@sun.com 			pt_sugg_pick();
3869338Srafael.vanoni@sun.com 
3879338Srafael.vanoni@sun.com 		/* Refresh display */
3889908Srafael.vanoni@sun.com 		if (!PT_ON_DUMP)
3899908Srafael.vanoni@sun.com 			pt_display_update();
3909908Srafael.vanoni@sun.com 
3919908Srafael.vanoni@sun.com 		if (root_user)
3929908Srafael.vanoni@sun.com 			pt_cpufreq_suggest();
3939338Srafael.vanoni@sun.com 
3949338Srafael.vanoni@sun.com 		/*
3959338Srafael.vanoni@sun.com 		 * Update the interval based on how long the CPU was in the
3969338Srafael.vanoni@sun.com 		 * longest c-state during the last snapshot. If the user
3979338Srafael.vanoni@sun.com 		 * specified an interval we skip this bit and keep it fixed.
3989338Srafael.vanoni@sun.com 		 */
39911122Srafael.vanoni@sun.com 		if (g_features & FEATURE_CSTATE && !PT_ON_TIME &&
40011122Srafael.vanoni@sun.com 		    g_longest_cstate > 0) {
40111122Srafael.vanoni@sun.com 			double deep_idle_res = (((double)
4029908Srafael.vanoni@sun.com 			    g_cstate_info[g_longest_cstate].total_time/MICROSEC
4039908Srafael.vanoni@sun.com 			    /g_ncpus)/g_cstate_info[g_longest_cstate].events);
4049338Srafael.vanoni@sun.com 
40511122Srafael.vanoni@sun.com 			if (deep_idle_res < INTERVAL_DEFAULT ||
40611122Srafael.vanoni@sun.com 			    (g_total_events/interval) < 1)
40711122Srafael.vanoni@sun.com 				interval = INTERVAL_DEFAULT;
4089338Srafael.vanoni@sun.com 			else
40911122Srafael.vanoni@sun.com 				interval = INTERVAL_UPDATE(deep_idle_res);
4109908Srafael.vanoni@sun.com 		} else {
4119908Srafael.vanoni@sun.com 			/*
4129908Srafael.vanoni@sun.com 			 * Restore interval after a refresh.
4139908Srafael.vanoni@sun.com 			 */
4149908Srafael.vanoni@sun.com 			if (key)
41511122Srafael.vanoni@sun.com 				interval = interval_usr;
4169908Srafael.vanoni@sun.com 		}
4179908Srafael.vanoni@sun.com 	}
4189338Srafael.vanoni@sun.com 
4199338Srafael.vanoni@sun.com 	return (EXIT_SUCCESS);
4209338Srafael.vanoni@sun.com }
421