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 <stdarg.h>
419338Srafael.vanoni@sun.com #include <stdlib.h>
429338Srafael.vanoni@sun.com #include <libgen.h>
439338Srafael.vanoni@sun.com #include <unistd.h>
449338Srafael.vanoni@sun.com #include <strings.h>
459338Srafael.vanoni@sun.com #include <sys/systeminfo.h>
469338Srafael.vanoni@sun.com #include <kstat.h>
479338Srafael.vanoni@sun.com #include <errno.h>
489338Srafael.vanoni@sun.com #include "powertop.h"
499338Srafael.vanoni@sun.com
509338Srafael.vanoni@sun.com static char PROG_FMT[] = "%s: ";
519338Srafael.vanoni@sun.com static char ERR_FMT[] = ": %s";
529338Srafael.vanoni@sun.com static char *progname;
539338Srafael.vanoni@sun.com
549338Srafael.vanoni@sun.com void
pt_set_progname(char * name)559338Srafael.vanoni@sun.com pt_set_progname(char *name)
569338Srafael.vanoni@sun.com {
579338Srafael.vanoni@sun.com progname = basename(name);
589338Srafael.vanoni@sun.com }
599338Srafael.vanoni@sun.com
609338Srafael.vanoni@sun.com /*PRINTFLIKE1*/
619338Srafael.vanoni@sun.com void
pt_error(char * format,...)629338Srafael.vanoni@sun.com pt_error(char *format, ...)
639338Srafael.vanoni@sun.com {
649338Srafael.vanoni@sun.com int err = errno;
659338Srafael.vanoni@sun.com va_list alist;
669338Srafael.vanoni@sun.com
679338Srafael.vanoni@sun.com if (g_gui)
689338Srafael.vanoni@sun.com return;
699338Srafael.vanoni@sun.com
709338Srafael.vanoni@sun.com if (progname != NULL)
719338Srafael.vanoni@sun.com (void) fprintf(stderr, PROG_FMT, progname);
729338Srafael.vanoni@sun.com
739338Srafael.vanoni@sun.com va_start(alist, format);
749338Srafael.vanoni@sun.com (void) vfprintf(stderr, format, alist);
759338Srafael.vanoni@sun.com va_end(alist);
769338Srafael.vanoni@sun.com
779338Srafael.vanoni@sun.com if (strchr(format, '\n') == NULL)
78*11122Srafael.vanoni@sun.com (void) fprintf(stderr, ERR_FMT, strerror(err));
799338Srafael.vanoni@sun.com }
809338Srafael.vanoni@sun.com
819338Srafael.vanoni@sun.com /*
829338Srafael.vanoni@sun.com * Returns the number of online CPUs.
839338Srafael.vanoni@sun.com */
849338Srafael.vanoni@sun.com uint_t
pt_enumerate_cpus(void)85*11122Srafael.vanoni@sun.com pt_enumerate_cpus(void)
869338Srafael.vanoni@sun.com {
879338Srafael.vanoni@sun.com int cpuid;
889338Srafael.vanoni@sun.com int max, cpus_conf;
899338Srafael.vanoni@sun.com uint_t ncpus = 0;
909338Srafael.vanoni@sun.com
919338Srafael.vanoni@sun.com max = sysconf(_SC_CPUID_MAX);
929338Srafael.vanoni@sun.com cpus_conf = sysconf(_SC_NPROCESSORS_CONF);
939338Srafael.vanoni@sun.com
949338Srafael.vanoni@sun.com /* Fall back to one CPU if any of the sysconf calls above failed */
959338Srafael.vanoni@sun.com if (max == -1 || cpus_conf == -1) {
969338Srafael.vanoni@sun.com max = cpus_conf = 1;
979338Srafael.vanoni@sun.com }
989338Srafael.vanoni@sun.com
999338Srafael.vanoni@sun.com if ((g_cpu_table = malloc(cpus_conf * sizeof (processorid_t))) == NULL)
1009338Srafael.vanoni@sun.com return (0);
1019338Srafael.vanoni@sun.com
1029338Srafael.vanoni@sun.com for (cpuid = 0; cpuid < max; cpuid++) {
1039338Srafael.vanoni@sun.com if (p_online(cpuid, P_STATUS) != -1) {
1049338Srafael.vanoni@sun.com g_cpu_table[ncpus] = cpuid;
1059338Srafael.vanoni@sun.com ncpus++;
1069338Srafael.vanoni@sun.com }
1079338Srafael.vanoni@sun.com }
1089338Srafael.vanoni@sun.com return (ncpus);
1099338Srafael.vanoni@sun.com }
1109338Srafael.vanoni@sun.com
1119338Srafael.vanoni@sun.com void
pt_usage(void)112*11122Srafael.vanoni@sun.com pt_usage(void)
1139338Srafael.vanoni@sun.com {
1149338Srafael.vanoni@sun.com (void) fprintf(stderr, "%s %s\n\n", TITLE, COPYRIGHT_INTEL);
115*11122Srafael.vanoni@sun.com (void) fprintf(stderr, "usage: powertop [option]\n");
1169338Srafael.vanoni@sun.com (void) fprintf(stderr, " -d, --dump [count] Read wakeups count "
1179338Srafael.vanoni@sun.com "times and print list of top offenders\n");
1189338Srafael.vanoni@sun.com (void) fprintf(stderr, " -t, --time [interval] Default time to gather "
119*11122Srafael.vanoni@sun.com "data in seconds [1-30s]\n");
1209338Srafael.vanoni@sun.com (void) fprintf(stderr, " -v, --verbose Verbose mode, reports "
1219338Srafael.vanoni@sun.com "kernel cyclic activity\n");
1229338Srafael.vanoni@sun.com (void) fprintf(stderr, " -c, --cpu [CPU] Only observe a specific"
1239338Srafael.vanoni@sun.com " CPU\n");
1249338Srafael.vanoni@sun.com (void) fprintf(stderr, " -h, --help Show this help "
1259338Srafael.vanoni@sun.com "message\n");
1269338Srafael.vanoni@sun.com }
1279338Srafael.vanoni@sun.com
1289338Srafael.vanoni@sun.com int
pt_get_bit_depth(void)129*11122Srafael.vanoni@sun.com pt_get_bit_depth(void)
1309338Srafael.vanoni@sun.com {
1319338Srafael.vanoni@sun.com /*
1329338Srafael.vanoni@sun.com * This little routine was derived from isainfo.c to look up
1339338Srafael.vanoni@sun.com * the system's bit depth. It feeds a 10 byte long buffer to
1349338Srafael.vanoni@sun.com * sysinfo (we only need the first word, sysinfo truncates and
1359338Srafael.vanoni@sun.com * \0 terminates the rest) from which we figure out which isa
1369338Srafael.vanoni@sun.com * we're running on.
1379338Srafael.vanoni@sun.com */
1389338Srafael.vanoni@sun.com char buf[BIT_DEPTH_BUF];
1399338Srafael.vanoni@sun.com
1409338Srafael.vanoni@sun.com if (sysinfo(SI_ARCHITECTURE_64, buf, BIT_DEPTH_BUF) == -1)
1419338Srafael.vanoni@sun.com if (sysinfo(SI_ARCHITECTURE_32, buf, BIT_DEPTH_BUF) == -1)
1429338Srafael.vanoni@sun.com return (-2);
1439338Srafael.vanoni@sun.com
1449338Srafael.vanoni@sun.com if (strcmp(buf, "sparc") == 0 || strcmp(buf, "i386") == 0)
1459338Srafael.vanoni@sun.com return (32);
1469338Srafael.vanoni@sun.com
1479338Srafael.vanoni@sun.com if (strcmp(buf, "sparcv9") == 0 || strcmp(buf, "amd64") == 0)
1489338Srafael.vanoni@sun.com return (64);
1499338Srafael.vanoni@sun.com
1509338Srafael.vanoni@sun.com return (-3);
1519338Srafael.vanoni@sun.com }
1529338Srafael.vanoni@sun.com
1539338Srafael.vanoni@sun.com /*
1549338Srafael.vanoni@sun.com * Simple integer comparison routine for the event report qsort(3C).
1559338Srafael.vanoni@sun.com */
1569338Srafael.vanoni@sun.com int
pt_event_compare(const void * p1,const void * p2)157*11122Srafael.vanoni@sun.com pt_event_compare(const void *p1, const void *p2)
1589338Srafael.vanoni@sun.com {
1599338Srafael.vanoni@sun.com event_info_t i = *((event_info_t *)p1);
1609338Srafael.vanoni@sun.com event_info_t j = *((event_info_t *)p2);
1619338Srafael.vanoni@sun.com
1629338Srafael.vanoni@sun.com if (i.total_count > j.total_count)
1639338Srafael.vanoni@sun.com return (-1);
1649338Srafael.vanoni@sun.com
1659338Srafael.vanoni@sun.com if (i.total_count < j.total_count)
1669338Srafael.vanoni@sun.com return (1);
1679338Srafael.vanoni@sun.com
1689338Srafael.vanoni@sun.com return (0);
1699338Srafael.vanoni@sun.com }
170