1b47b5b34SRafael Vanoni /*
2b47b5b34SRafael Vanoni * Copyright 2009, Intel Corporation
3b47b5b34SRafael Vanoni * Copyright 2009, Sun Microsystems, Inc
4b47b5b34SRafael Vanoni *
5b47b5b34SRafael Vanoni * This file is part of PowerTOP
6b47b5b34SRafael Vanoni *
7b47b5b34SRafael Vanoni * This program file is free software; you can redistribute it and/or modify it
8b47b5b34SRafael Vanoni * under the terms of the GNU General Public License as published by the
9b47b5b34SRafael Vanoni * Free Software Foundation; version 2 of the License.
10b47b5b34SRafael Vanoni *
11b47b5b34SRafael Vanoni * This program is distributed in the hope that it will be useful, but WITHOUT
12b47b5b34SRafael Vanoni * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13b47b5b34SRafael Vanoni * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14b47b5b34SRafael Vanoni * for more details.
15b47b5b34SRafael Vanoni *
16b47b5b34SRafael Vanoni * You should have received a copy of the GNU General Public License
17b47b5b34SRafael Vanoni * along with this program in a file named COPYING; if not, write to the
18b47b5b34SRafael Vanoni * Free Software Foundation, Inc.,
19b47b5b34SRafael Vanoni * 51 Franklin Street, Fifth Floor,
20b47b5b34SRafael Vanoni * Boston, MA 02110-1301 USA
21b47b5b34SRafael Vanoni *
22b47b5b34SRafael Vanoni * Authors:
23b47b5b34SRafael Vanoni * Arjan van de Ven <arjan@linux.intel.com>
24b47b5b34SRafael Vanoni * Eric C Saxe <eric.saxe@sun.com>
25b47b5b34SRafael Vanoni * Aubrey Li <aubrey.li@intel.com>
26b47b5b34SRafael Vanoni */
27b47b5b34SRafael Vanoni
28b47b5b34SRafael Vanoni /*
29b47b5b34SRafael Vanoni * GPL Disclaimer
30b47b5b34SRafael Vanoni *
31b47b5b34SRafael Vanoni * For the avoidance of doubt, except that if any license choice other
32b47b5b34SRafael Vanoni * than GPL or LGPL is available it will apply instead, Sun elects to
33b47b5b34SRafael Vanoni * use only the General Public License version 2 (GPLv2) at this time
34b47b5b34SRafael Vanoni * for any software where a choice of GPL license versions is made
35b47b5b34SRafael Vanoni * available with the language indicating that GPLv2 or any later
36b47b5b34SRafael Vanoni * version may be used, or where a choice of which version of the GPL
37b47b5b34SRafael Vanoni * is applied is otherwise unspecified.
38b47b5b34SRafael Vanoni */
39b47b5b34SRafael Vanoni
40b47b5b34SRafael Vanoni #include <getopt.h>
41b47b5b34SRafael Vanoni #include <unistd.h>
42b47b5b34SRafael Vanoni #include <stdio.h>
43b47b5b34SRafael Vanoni #include <stdlib.h>
449bbf5ba1SRafael Vanoni #include <signal.h>
45b47b5b34SRafael Vanoni #include <string.h>
46b47b5b34SRafael Vanoni #include <ctype.h>
472d83778aSRafael Vanoni #include <poll.h>
48b47b5b34SRafael Vanoni #include "powertop.h"
49b47b5b34SRafael Vanoni
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;
55636423dbSRafael Vanoni 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
61b47b5b34SRafael Vanoni 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
70b47b5b34SRafael Vanoni 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
75b47b5b34SRafael Vanoni boolean_t g_turbo_supported;
762d83778aSRafael Vanoni boolean_t g_sig_resize;
77b47b5b34SRafael Vanoni
78b47b5b34SRafael Vanoni uint_t g_argc;
79b47b5b34SRafael Vanoni char **g_argv;
80b47b5b34SRafael Vanoni
81b47b5b34SRafael Vanoni char *optarg;
82b47b5b34SRafael Vanoni
83b47b5b34SRafael Vanoni static const int true = 1;
84b47b5b34SRafael Vanoni
852d83778aSRafael Vanoni void
pt_sig_handler(int sig)862d83778aSRafael Vanoni pt_sig_handler(int sig)
872d83778aSRafael Vanoni {
882d83778aSRafael Vanoni switch (sig) {
892d83778aSRafael Vanoni case SIGWINCH:
902d83778aSRafael Vanoni g_sig_resize = B_TRUE;
912d83778aSRafael Vanoni break;
922d83778aSRafael Vanoni }
932d83778aSRafael Vanoni }
942d83778aSRafael Vanoni
95b47b5b34SRafael Vanoni int
main(int argc,char ** argv)96b47b5b34SRafael Vanoni main(int argc, char **argv)
97b47b5b34SRafael Vanoni {
982d83778aSRafael Vanoni double interval, interval_usr;
992d83778aSRafael Vanoni hrtime_t interval_start;
1002d83778aSRafael Vanoni int index2 = 0, c, dump_count = 0;
1012d83778aSRafael Vanoni char *endptr, key;
1029bbf5ba1SRafael Vanoni boolean_t root_user = B_FALSE;
1032d83778aSRafael Vanoni struct pollfd pollset;
104b47b5b34SRafael Vanoni
105b47b5b34SRafael Vanoni static struct option opts[] = {
106b47b5b34SRafael Vanoni { "dump", 1, NULL, 'd' },
107b47b5b34SRafael Vanoni { "time", 1, NULL, 't' },
108b47b5b34SRafael Vanoni { "help", 0, NULL, 'h' },
109b47b5b34SRafael Vanoni { "cpu", 1, NULL, 'c' },
110b47b5b34SRafael Vanoni { "verbose", 0, NULL, 'v' },
111b47b5b34SRafael Vanoni { 0, 0, NULL, 0 }
112b47b5b34SRafael Vanoni };
113b47b5b34SRafael Vanoni
114b47b5b34SRafael Vanoni pt_set_progname(argv[0]);
115b47b5b34SRafael Vanoni
116b47b5b34SRafael Vanoni /*
1179bbf5ba1SRafael Vanoni * Enumerate the system's CPUs, populate cpu_table, g_ncpus
118b47b5b34SRafael Vanoni */
1192d83778aSRafael Vanoni if ((g_ncpus = g_ncpus_observed = pt_enumerate_cpus()) == 0)
120b47b5b34SRafael Vanoni exit(EXIT_FAILURE);
121b47b5b34SRafael Vanoni
1222d83778aSRafael Vanoni if ((g_bit_depth = pt_get_bit_depth()) < 0)
123b47b5b34SRafael Vanoni exit(EXIT_FAILURE);
124b47b5b34SRafael Vanoni
1259bbf5ba1SRafael Vanoni g_features = 0;
1262d83778aSRafael Vanoni interval = interval_usr = INTERVAL_DEFAULT;
127636423dbSRafael Vanoni g_op_mode = PT_MODE_DEFAULT;
128b47b5b34SRafael Vanoni g_max_cstate = 0;
129b47b5b34SRafael Vanoni g_argv = NULL;
130b47b5b34SRafael Vanoni g_argc = 0;
131b47b5b34SRafael Vanoni g_observed_cpu = 0;
132b47b5b34SRafael Vanoni g_turbo_supported = B_FALSE;
1332d83778aSRafael Vanoni g_sig_resize = B_FALSE;
1349bbf5ba1SRafael Vanoni g_curr_sugg = NULL;
135b47b5b34SRafael Vanoni
1362d83778aSRafael Vanoni while ((c = getopt_long(argc, argv, "d:t:hvc:", opts, &index2))
137b47b5b34SRafael Vanoni != EOF) {
138b47b5b34SRafael Vanoni if (c == -1)
139b47b5b34SRafael Vanoni break;
140b47b5b34SRafael Vanoni
141b47b5b34SRafael Vanoni switch (c) {
142b47b5b34SRafael Vanoni case 'd':
1432d83778aSRafael Vanoni if (PT_ON_DUMP) {
1442d83778aSRafael Vanoni pt_usage();
1452d83778aSRafael Vanoni exit(EXIT_USAGE);
1462d83778aSRafael Vanoni }
147b47b5b34SRafael Vanoni
148636423dbSRafael Vanoni g_op_mode |= PT_MODE_DUMP;
1492d83778aSRafael Vanoni g_gui = B_FALSE;
150b47b5b34SRafael Vanoni dump_count = (int)strtod(optarg, &endptr);
151b47b5b34SRafael Vanoni
152c77fd2f1SRafael Vanoni if (dump_count <= 0 || *endptr != NULL) {
1532d83778aSRafael Vanoni pt_usage();
154c77fd2f1SRafael Vanoni exit(EXIT_USAGE);
155c77fd2f1SRafael Vanoni }
156c77fd2f1SRafael Vanoni
157b47b5b34SRafael Vanoni break;
158b47b5b34SRafael Vanoni case 't':
1592d83778aSRafael Vanoni if (PT_ON_TIME) {
1602d83778aSRafael Vanoni pt_usage();
1612d83778aSRafael Vanoni exit(EXIT_USAGE);
1622d83778aSRafael Vanoni }
163b47b5b34SRafael Vanoni
1642d83778aSRafael Vanoni g_op_mode |= PT_MODE_TIME;
1652d83778aSRafael Vanoni interval = interval_usr = (double)strtod(optarg,
166b47b5b34SRafael Vanoni &endptr);
167b47b5b34SRafael Vanoni
1682d83778aSRafael Vanoni if (*endptr != NULL || interval < 1 ||
1692d83778aSRafael Vanoni interval > INTERVAL_MAX) {
1702d83778aSRafael Vanoni pt_usage();
1712d83778aSRafael Vanoni exit(EXIT_USAGE);
1722d83778aSRafael Vanoni }
1732d83778aSRafael Vanoni
174b47b5b34SRafael Vanoni break;
175b47b5b34SRafael Vanoni case 'v':
1762d83778aSRafael Vanoni if (PT_ON_CPU || PT_ON_VERBOSE) {
1772d83778aSRafael Vanoni pt_usage();
1782d83778aSRafael Vanoni exit(EXIT_USAGE);
1792d83778aSRafael Vanoni }
180b47b5b34SRafael Vanoni
181636423dbSRafael Vanoni g_op_mode |= PT_MODE_VERBOSE;
182b47b5b34SRafael Vanoni break;
183b47b5b34SRafael Vanoni case 'c':
1842d83778aSRafael Vanoni if (PT_ON_CPU || PT_ON_VERBOSE) {
1852d83778aSRafael Vanoni pt_usage();
1862d83778aSRafael Vanoni exit(EXIT_USAGE);
1872d83778aSRafael Vanoni }
188b47b5b34SRafael Vanoni
189636423dbSRafael Vanoni g_op_mode |= PT_MODE_CPU;
190b47b5b34SRafael Vanoni g_observed_cpu = (uint_t)strtod(optarg, &endptr);
191b47b5b34SRafael Vanoni
1922d83778aSRafael Vanoni if (g_observed_cpu >= g_ncpus) {
1932d83778aSRafael Vanoni pt_usage();
1942d83778aSRafael Vanoni exit(EXIT_USAGE);
1952d83778aSRafael Vanoni }
196b47b5b34SRafael Vanoni
197b47b5b34SRafael Vanoni g_argc = 1;
198b47b5b34SRafael Vanoni g_ncpus_observed = 1;
199b47b5b34SRafael Vanoni
200b47b5b34SRafael Vanoni if ((g_argv = malloc(sizeof (char *))) == NULL)
201b47b5b34SRafael Vanoni return (EXIT_FAILURE);
202b47b5b34SRafael Vanoni
203b47b5b34SRafael Vanoni if ((*g_argv = malloc(sizeof (char) * 5)) == NULL)
204b47b5b34SRafael Vanoni return (EXIT_FAILURE);
205b47b5b34SRafael Vanoni
206b47b5b34SRafael Vanoni (void) snprintf(*g_argv, 5, "%d\0", g_observed_cpu);
207b47b5b34SRafael Vanoni break;
208b47b5b34SRafael Vanoni case 'h':
2092d83778aSRafael Vanoni pt_usage();
2102d83778aSRafael Vanoni exit(EXIT_SUCCESS);
211b47b5b34SRafael Vanoni default:
2122d83778aSRafael Vanoni pt_usage();
2132d83778aSRafael Vanoni exit(EXIT_USAGE);
214b47b5b34SRafael Vanoni }
215b47b5b34SRafael Vanoni }
216b47b5b34SRafael Vanoni
217c77fd2f1SRafael Vanoni if (optind < argc) {
2182d83778aSRafael Vanoni pt_usage();
219c77fd2f1SRafael Vanoni exit(EXIT_USAGE);
220c77fd2f1SRafael Vanoni }
221b47b5b34SRafael Vanoni
222b47b5b34SRafael Vanoni (void) printf("%s %s\n\n", TITLE, COPYRIGHT_INTEL);
223b47b5b34SRafael Vanoni
2242d83778aSRafael Vanoni (void) printf("Collecting data for %.2f second(s) \n",
2252d83778aSRafael Vanoni (float)interval);
2269bbf5ba1SRafael Vanoni
2279bbf5ba1SRafael Vanoni /* Prepare P-state statistics */
2289bbf5ba1SRafael Vanoni if (pt_cpufreq_stat_prepare() == 0)
2299bbf5ba1SRafael Vanoni g_features |= FEATURE_PSTATE;
230b47b5b34SRafael Vanoni
231b47b5b34SRafael Vanoni /* Prepare C-state statistics */
2322d83778aSRafael Vanoni if (pt_cpuidle_stat_prepare() == 0)
2339bbf5ba1SRafael Vanoni g_features |= FEATURE_CSTATE;
234b47b5b34SRafael Vanoni else
235b47b5b34SRafael Vanoni /*
236b47b5b34SRafael Vanoni * PowerTop was unable to run a DTrace program,
237b47b5b34SRafael Vanoni * most likely for lack of permissions.
238b47b5b34SRafael Vanoni */
239b47b5b34SRafael Vanoni exit(EXIT_FAILURE);
240b47b5b34SRafael Vanoni
241b47b5b34SRafael Vanoni /* Prepare event statistics */
242b47b5b34SRafael Vanoni if (pt_events_stat_prepare() != -1)
2439bbf5ba1SRafael Vanoni g_features |= FEATURE_EVENTS;
2449bbf5ba1SRafael Vanoni
2459bbf5ba1SRafael Vanoni /*
2469bbf5ba1SRafael Vanoni * If the system is running on battery, find out what's
2479bbf5ba1SRafael Vanoni * the kstat module for it
2489bbf5ba1SRafael Vanoni */
2492d83778aSRafael Vanoni pt_battery_mod_lookup();
250b47b5b34SRafael Vanoni
251b47b5b34SRafael Vanoni /* Prepare turbo statistics */
2529bbf5ba1SRafael Vanoni if (pt_turbo_stat_prepare() == 0)
2539bbf5ba1SRafael Vanoni g_features |= FEATURE_TURBO;
2549bbf5ba1SRafael Vanoni
2559bbf5ba1SRafael Vanoni /*
2562d83778aSRafael Vanoni * Initialize the display.
2572d83778aSRafael Vanoni */
2582d83778aSRafael Vanoni if (!PT_ON_DUMP) {
2592d83778aSRafael Vanoni pt_display_init_curses();
2602d83778aSRafael Vanoni pt_display_setup(B_FALSE);
2612d83778aSRafael Vanoni (void) signal(SIGWINCH, pt_sig_handler);
2622d83778aSRafael Vanoni
2632d83778aSRafael Vanoni pt_display_title_bar();
2642d83778aSRafael Vanoni pt_display_status_bar();
2652d83778aSRafael Vanoni
2662d83778aSRafael Vanoni g_gui = B_TRUE;
2672d83778aSRafael Vanoni pollset.fd = STDIN_FILENO;
2682d83778aSRafael Vanoni pollset.events = POLLIN;
2692d83778aSRafael Vanoni }
2702d83778aSRafael Vanoni
2712d83778aSRafael Vanoni /*
2729bbf5ba1SRafael Vanoni * Installs the initial suggestions, running as root and turning CPU
2739bbf5ba1SRafael Vanoni * power management ON.
2749bbf5ba1SRafael Vanoni */
2752d83778aSRafael Vanoni if (geteuid() != 0) {
2769bbf5ba1SRafael Vanoni pt_sugg_as_root();
2772d83778aSRafael Vanoni } else {
2789bbf5ba1SRafael Vanoni root_user = B_TRUE;
2799bbf5ba1SRafael Vanoni pt_cpufreq_suggest();
280b47b5b34SRafael Vanoni }
281b47b5b34SRafael Vanoni
282b47b5b34SRafael Vanoni while (true) {
2832d83778aSRafael Vanoni key = 0;
284b47b5b34SRafael Vanoni
2852d83778aSRafael Vanoni if (g_sig_resize)
2862d83778aSRafael Vanoni pt_display_resize();
287b47b5b34SRafael Vanoni
2882d83778aSRafael Vanoni interval_start = gethrtime();
289b47b5b34SRafael Vanoni
2909bbf5ba1SRafael Vanoni if (!PT_ON_DUMP) {
2912d83778aSRafael Vanoni if (poll(&pollset, (nfds_t)1,
2922d83778aSRafael Vanoni (int)(interval * MILLISEC)) > 0)
2932d83778aSRafael Vanoni (void) read(STDIN_FILENO, &key, 1);
2942d83778aSRafael Vanoni } else {
2952d83778aSRafael Vanoni (void) sleep((int)interval);
2962d83778aSRafael Vanoni }
297b47b5b34SRafael Vanoni
2982d83778aSRafael Vanoni g_interval_length = (double)(gethrtime() - interval_start)
2992d83778aSRafael Vanoni /NANOSEC;
300b47b5b34SRafael Vanoni
301636423dbSRafael Vanoni g_top_events = 0;
302b47b5b34SRafael Vanoni g_total_events = 0;
303b47b5b34SRafael Vanoni
3049b37b909SRafael Vanoni (void) memset(g_event_info, 0,
3059b37b909SRafael Vanoni EVENT_NUM_MAX * sizeof (event_info_t));
30692ad8f28SRafael Vanoni (void) memset(g_cstate_info, 0,
30792ad8f28SRafael Vanoni NSTATES * sizeof (state_info_t));
308b47b5b34SRafael Vanoni
309b47b5b34SRafael Vanoni /* Collect idle state transition stats */
3109bbf5ba1SRafael Vanoni if (g_features & FEATURE_CSTATE &&
3112d83778aSRafael Vanoni pt_cpuidle_stat_collect(g_interval_length) < 0) {
312b47b5b34SRafael Vanoni /* Reinitialize C-state statistics */
313b47b5b34SRafael Vanoni if (pt_cpuidle_stat_prepare() != 0)
314b47b5b34SRafael Vanoni exit(EXIT_FAILURE);
315b47b5b34SRafael Vanoni
3169bbf5ba1SRafael Vanoni continue;
317b47b5b34SRafael Vanoni }
318b47b5b34SRafael Vanoni
319b47b5b34SRafael Vanoni /* Collect frequency change stats */
3209bbf5ba1SRafael Vanoni if (g_features & FEATURE_PSTATE &&
3212d83778aSRafael Vanoni pt_cpufreq_stat_collect(g_interval_length) < 0) {
322b47b5b34SRafael Vanoni /* Reinitialize P-state statistics */
323b47b5b34SRafael Vanoni if (pt_cpufreq_stat_prepare() != 0)
324b47b5b34SRafael Vanoni exit(EXIT_FAILURE);
325b47b5b34SRafael Vanoni
3269bbf5ba1SRafael Vanoni continue;
327b47b5b34SRafael Vanoni }
328b47b5b34SRafael Vanoni
329b47b5b34SRafael Vanoni /* Collect event statistics */
3309bbf5ba1SRafael Vanoni if (g_features & FEATURE_EVENTS &&
331b47b5b34SRafael Vanoni pt_events_stat_collect() < 0) {
332b47b5b34SRafael Vanoni /* Reinitialize event statistics */
333b47b5b34SRafael Vanoni if (pt_events_stat_prepare() != 0)
334b47b5b34SRafael Vanoni exit(EXIT_FAILURE);
335b47b5b34SRafael Vanoni
336b47b5b34SRafael Vanoni continue;
3379bbf5ba1SRafael Vanoni }
338b47b5b34SRafael Vanoni
339b47b5b34SRafael Vanoni /* Collect turbo statistics */
3409bbf5ba1SRafael Vanoni if (g_features & FEATURE_TURBO &&
3419bbf5ba1SRafael Vanoni pt_turbo_stat_collect() < 0)
342b47b5b34SRafael Vanoni exit(EXIT_FAILURE);
343b47b5b34SRafael Vanoni
344b47b5b34SRafael Vanoni /* Show CPU power states */
3459bbf5ba1SRafael Vanoni pt_display_states();
346b47b5b34SRafael Vanoni
347b47b5b34SRafael Vanoni /* Show wakeups events affecting PM */
3489bbf5ba1SRafael Vanoni if (g_features & FEATURE_EVENTS) {
3492d83778aSRafael Vanoni pt_display_wakeups(g_interval_length);
3502d83778aSRafael Vanoni pt_display_events(g_interval_length);
351b47b5b34SRafael Vanoni }
352b47b5b34SRafael Vanoni
3539bbf5ba1SRafael Vanoni pt_battery_print();
354b47b5b34SRafael Vanoni
355636423dbSRafael Vanoni if (key && !PT_ON_DUMP) {
3562d83778aSRafael Vanoni switch (toupper(key)) {
357b47b5b34SRafael Vanoni case 'Q':
358b47b5b34SRafael Vanoni exit(EXIT_SUCCESS);
359b47b5b34SRafael Vanoni break;
3609bbf5ba1SRafael Vanoni
361b47b5b34SRafael Vanoni case 'R':
3622d83778aSRafael Vanoni interval = 3;
363b47b5b34SRafael Vanoni break;
364b47b5b34SRafael Vanoni }
365b47b5b34SRafael Vanoni
3669bbf5ba1SRafael Vanoni /*
3679bbf5ba1SRafael Vanoni * Check if the user has activated the current
3689bbf5ba1SRafael Vanoni * suggestion.
3699bbf5ba1SRafael Vanoni */
3709bbf5ba1SRafael Vanoni if (g_curr_sugg != NULL &&
3712d83778aSRafael Vanoni toupper(key) == g_curr_sugg->key &&
3722d83778aSRafael Vanoni g_curr_sugg->func)
3739bbf5ba1SRafael Vanoni g_curr_sugg->func();
374b47b5b34SRafael Vanoni }
375b47b5b34SRafael Vanoni
376b47b5b34SRafael Vanoni if (dump_count)
377b47b5b34SRafael Vanoni dump_count--;
378b47b5b34SRafael Vanoni
379b47b5b34SRafael Vanoni /* Exits if user requested a dump */
3809bbf5ba1SRafael Vanoni if (PT_ON_DUMP && !dump_count)
381b47b5b34SRafael Vanoni exit(EXIT_SUCCESS);
382b47b5b34SRafael Vanoni
383b47b5b34SRafael Vanoni /* No key pressed, will suggest something */
384b47b5b34SRafael Vanoni if (!key && !dump_count)
3859bbf5ba1SRafael Vanoni pt_sugg_pick();
386b47b5b34SRafael Vanoni
387b47b5b34SRafael Vanoni /* Refresh display */
3889bbf5ba1SRafael Vanoni if (!PT_ON_DUMP)
3899bbf5ba1SRafael Vanoni pt_display_update();
3909bbf5ba1SRafael Vanoni
3919bbf5ba1SRafael Vanoni if (root_user)
3929bbf5ba1SRafael Vanoni pt_cpufreq_suggest();
393b47b5b34SRafael Vanoni
394b47b5b34SRafael Vanoni /*
395b47b5b34SRafael Vanoni * Update the interval based on how long the CPU was in the
396b47b5b34SRafael Vanoni * longest c-state during the last snapshot. If the user
397b47b5b34SRafael Vanoni * specified an interval we skip this bit and keep it fixed.
398b47b5b34SRafael Vanoni */
3992d83778aSRafael Vanoni if (g_features & FEATURE_CSTATE && !PT_ON_TIME &&
400*b54d0971SMilan Jurik g_longest_cstate > 0 &&
401*b54d0971SMilan Jurik g_cstate_info[g_longest_cstate].events > 0) {
4022d83778aSRafael Vanoni double deep_idle_res = (((double)
4039bbf5ba1SRafael Vanoni g_cstate_info[g_longest_cstate].total_time/MICROSEC
4049bbf5ba1SRafael Vanoni /g_ncpus)/g_cstate_info[g_longest_cstate].events);
405b47b5b34SRafael Vanoni
4062d83778aSRafael Vanoni if (deep_idle_res < INTERVAL_DEFAULT ||
4072d83778aSRafael Vanoni (g_total_events/interval) < 1)
4082d83778aSRafael Vanoni interval = INTERVAL_DEFAULT;
409b47b5b34SRafael Vanoni else
4102d83778aSRafael Vanoni interval = INTERVAL_UPDATE(deep_idle_res);
4119bbf5ba1SRafael Vanoni } else {
412b47b5b34SRafael Vanoni /*
4139bbf5ba1SRafael Vanoni * Restore interval after a refresh.
414b47b5b34SRafael Vanoni */
4159bbf5ba1SRafael Vanoni if (key)
4162d83778aSRafael Vanoni interval = interval_usr;
417b47b5b34SRafael Vanoni }
418b47b5b34SRafael Vanoni }
419b47b5b34SRafael Vanoni
4209bbf5ba1SRafael Vanoni return (EXIT_SUCCESS);
421b47b5b34SRafael Vanoni }
422