/*
* Copyright 2009, Intel Corporation
* Copyright 2009, Sun Microsystems, Inc
*
* This file is part of PowerTOP
*
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program in a file named COPYING; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* Authors:
* Arjan van de Ven <arjan@linux.intel.com>
* Eric C Saxe <eric.saxe@sun.com>
* Aubrey Li <aubrey.li@intel.com>
*/
/*
* GPL Disclaimer
*
* For the avoidance of doubt, except that if any license choice other
* than GPL or LGPL is available it will apply instead, Sun elects to
* use only the General Public License version 2 (GPLv2) at this time
* for any software where a choice of GPL license versions is made
* available with the language indicating that GPLv2 or any later
* version may be used, or where a choice of which version of the GPL
* is applied is otherwise unspecified.
*/
#include <getopt.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
#include <poll.h>
#include "powertop.h"
/*
* Global variables, see powertop.h for comments and extern declarations.
* These are ordered by type, grouped by usage.
*/
int g_bit_depth;
double g_interval_length;
char **g_argv;
static const int true = 1;
void
{
switch (sig) {
case SIGWINCH:
break;
}
}
int
{
{ 0, 0, NULL, 0 }
};
pt_set_progname(argv[0]);
/*
* Enumerate the system's CPUs, populate cpu_table, g_ncpus
*/
if ((g_bit_depth = pt_get_bit_depth()) < 0)
g_features = 0;
g_max_cstate = 0;
g_argc = 0;
g_observed_cpu = 0;
g_curr_sugg = NULL;
!= EOF) {
if (c == -1)
break;
switch (c) {
case 'd':
if (PT_ON_DUMP) {
pt_usage();
}
pt_usage();
}
break;
case 't':
if (PT_ON_TIME) {
pt_usage();
}
&endptr);
interval > INTERVAL_MAX) {
pt_usage();
}
break;
case 'v':
if (PT_ON_CPU || PT_ON_VERBOSE) {
pt_usage();
}
break;
case 'c':
if (PT_ON_CPU || PT_ON_VERBOSE) {
pt_usage();
}
g_op_mode |= PT_MODE_CPU;
if (g_observed_cpu >= g_ncpus) {
pt_usage();
}
g_argc = 1;
g_ncpus_observed = 1;
return (EXIT_FAILURE);
return (EXIT_FAILURE);
break;
case 'h':
pt_usage();
default:
pt_usage();
}
}
pt_usage();
}
(void) printf("Collecting data for %.2f second(s) \n",
(float)interval);
/* Prepare P-state statistics */
if (pt_cpufreq_stat_prepare() == 0)
/* Prepare C-state statistics */
if (pt_cpuidle_stat_prepare() == 0)
else
/*
* PowerTop was unable to run a DTrace program,
* most likely for lack of permissions.
*/
/* Prepare event statistics */
if (pt_events_stat_prepare() != -1)
/*
* If the system is running on battery, find out what's
* the kstat module for it
*/
/* Prepare turbo statistics */
if (pt_turbo_stat_prepare() == 0)
/*
* Initialize the display.
*/
if (!PT_ON_DUMP) {
}
/*
* Installs the initial suggestions, running as root and turning CPU
* power management ON.
*/
if (geteuid() != 0) {
} else {
}
while (true) {
key = 0;
if (g_sig_resize)
interval_start = gethrtime();
if (!PT_ON_DUMP) {
} else {
}
/NANOSEC;
g_top_events = 0;
g_total_events = 0;
(void) memset(g_event_info, 0,
EVENT_NUM_MAX * sizeof (event_info_t));
(void) memset(g_cstate_info, 0,
NSTATES * sizeof (state_info_t));
/* Collect idle state transition stats */
if (g_features & FEATURE_CSTATE &&
/* Reinitialize C-state statistics */
if (pt_cpuidle_stat_prepare() != 0)
continue;
}
/* Collect frequency change stats */
if (g_features & FEATURE_PSTATE &&
/* Reinitialize P-state statistics */
if (pt_cpufreq_stat_prepare() != 0)
continue;
}
/* Collect event statistics */
if (g_features & FEATURE_EVENTS &&
pt_events_stat_collect() < 0) {
/* Reinitialize event statistics */
if (pt_events_stat_prepare() != 0)
continue;
}
/* Collect turbo statistics */
if (g_features & FEATURE_TURBO &&
pt_turbo_stat_collect() < 0)
/* Show CPU power states */
/* Show wakeups events affecting PM */
if (g_features & FEATURE_EVENTS) {
}
if (key && !PT_ON_DUMP) {
case 'Q':
break;
case 'R':
interval = 3;
break;
}
/*
* Check if the user has activated the current
* suggestion.
*/
if (g_curr_sugg != NULL &&
g_curr_sugg->func();
}
if (dump_count)
dump_count--;
/* Exits if user requested a dump */
if (PT_ON_DUMP && !dump_count)
/* No key pressed, will suggest something */
if (!key && !dump_count)
pt_sugg_pick();
/* Refresh display */
if (!PT_ON_DUMP)
if (root_user)
/*
* Update the interval based on how long the CPU was in the
* longest c-state during the last snapshot. If the user
* specified an interval we skip this bit and keep it fixed.
*/
g_longest_cstate > 0 &&
double deep_idle_res = (((double)
if (deep_idle_res < INTERVAL_DEFAULT ||
else
} else {
/*
* Restore interval after a refresh.
*/
if (key)
}
}
return (EXIT_SUCCESS);
}