1*9338Srafael.vanoni@sun.com /* 2*9338Srafael.vanoni@sun.com * Copyright 2009, Intel Corporation 3*9338Srafael.vanoni@sun.com * Copyright 2009, Sun Microsystems, Inc 4*9338Srafael.vanoni@sun.com * 5*9338Srafael.vanoni@sun.com * This file is part of PowerTOP 6*9338Srafael.vanoni@sun.com * 7*9338Srafael.vanoni@sun.com * This program file is free software; you can redistribute it and/or modify it 8*9338Srafael.vanoni@sun.com * under the terms of the GNU General Public License as published by the 9*9338Srafael.vanoni@sun.com * Free Software Foundation; version 2 of the License. 10*9338Srafael.vanoni@sun.com * 11*9338Srafael.vanoni@sun.com * This program is distributed in the hope that it will be useful, but WITHOUT 12*9338Srafael.vanoni@sun.com * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*9338Srafael.vanoni@sun.com * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14*9338Srafael.vanoni@sun.com * for more details. 15*9338Srafael.vanoni@sun.com * 16*9338Srafael.vanoni@sun.com * You should have received a copy of the GNU General Public License 17*9338Srafael.vanoni@sun.com * along with this program in a file named COPYING; if not, write to the 18*9338Srafael.vanoni@sun.com * Free Software Foundation, Inc., 19*9338Srafael.vanoni@sun.com * 51 Franklin Street, Fifth Floor, 20*9338Srafael.vanoni@sun.com * Boston, MA 02110-1301 USA 21*9338Srafael.vanoni@sun.com * 22*9338Srafael.vanoni@sun.com * Authors: 23*9338Srafael.vanoni@sun.com * Arjan van de Ven <arjan@linux.intel.com> 24*9338Srafael.vanoni@sun.com * Eric C Saxe <eric.saxe@sun.com> 25*9338Srafael.vanoni@sun.com * Aubrey Li <aubrey.li@intel.com> 26*9338Srafael.vanoni@sun.com */ 27*9338Srafael.vanoni@sun.com 28*9338Srafael.vanoni@sun.com /* 29*9338Srafael.vanoni@sun.com * GPL Disclaimer 30*9338Srafael.vanoni@sun.com * 31*9338Srafael.vanoni@sun.com * For the avoidance of doubt, except that if any license choice other 32*9338Srafael.vanoni@sun.com * than GPL or LGPL is available it will apply instead, Sun elects to 33*9338Srafael.vanoni@sun.com * use only the General Public License version 2 (GPLv2) at this time 34*9338Srafael.vanoni@sun.com * for any software where a choice of GPL license versions is made 35*9338Srafael.vanoni@sun.com * available with the language indicating that GPLv2 or any later 36*9338Srafael.vanoni@sun.com * version may be used, or where a choice of which version of the GPL 37*9338Srafael.vanoni@sun.com * is applied is otherwise unspecified. 38*9338Srafael.vanoni@sun.com */ 39*9338Srafael.vanoni@sun.com 40*9338Srafael.vanoni@sun.com #include <stdarg.h> 41*9338Srafael.vanoni@sun.com #include <stdlib.h> 42*9338Srafael.vanoni@sun.com #include <libgen.h> 43*9338Srafael.vanoni@sun.com #include <unistd.h> 44*9338Srafael.vanoni@sun.com #include <strings.h> 45*9338Srafael.vanoni@sun.com #include <sys/systeminfo.h> 46*9338Srafael.vanoni@sun.com #include <kstat.h> 47*9338Srafael.vanoni@sun.com #include <errno.h> 48*9338Srafael.vanoni@sun.com #include "powertop.h" 49*9338Srafael.vanoni@sun.com 50*9338Srafael.vanoni@sun.com static char PROG_FMT[] = "%s: "; 51*9338Srafael.vanoni@sun.com static char ERR_FMT[] = ": %s"; 52*9338Srafael.vanoni@sun.com static char *progname; 53*9338Srafael.vanoni@sun.com 54*9338Srafael.vanoni@sun.com void 55*9338Srafael.vanoni@sun.com pt_set_progname(char *name) 56*9338Srafael.vanoni@sun.com { 57*9338Srafael.vanoni@sun.com progname = basename(name); 58*9338Srafael.vanoni@sun.com } 59*9338Srafael.vanoni@sun.com 60*9338Srafael.vanoni@sun.com /*PRINTFLIKE1*/ 61*9338Srafael.vanoni@sun.com void 62*9338Srafael.vanoni@sun.com pt_error(char *format, ...) 63*9338Srafael.vanoni@sun.com { 64*9338Srafael.vanoni@sun.com int err = errno; 65*9338Srafael.vanoni@sun.com va_list alist; 66*9338Srafael.vanoni@sun.com 67*9338Srafael.vanoni@sun.com if (g_gui) 68*9338Srafael.vanoni@sun.com return; 69*9338Srafael.vanoni@sun.com 70*9338Srafael.vanoni@sun.com if (progname != NULL) 71*9338Srafael.vanoni@sun.com (void) fprintf(stderr, PROG_FMT, progname); 72*9338Srafael.vanoni@sun.com 73*9338Srafael.vanoni@sun.com va_start(alist, format); 74*9338Srafael.vanoni@sun.com (void) vfprintf(stderr, format, alist); 75*9338Srafael.vanoni@sun.com va_end(alist); 76*9338Srafael.vanoni@sun.com 77*9338Srafael.vanoni@sun.com if (strchr(format, '\n') == NULL) 78*9338Srafael.vanoni@sun.com (void) fprintf(stderr, gettext(ERR_FMT), strerror(err)); 79*9338Srafael.vanoni@sun.com } 80*9338Srafael.vanoni@sun.com 81*9338Srafael.vanoni@sun.com /* 82*9338Srafael.vanoni@sun.com * Returns the number of online CPUs. 83*9338Srafael.vanoni@sun.com */ 84*9338Srafael.vanoni@sun.com uint_t 85*9338Srafael.vanoni@sun.com enumerate_cpus(void) 86*9338Srafael.vanoni@sun.com { 87*9338Srafael.vanoni@sun.com int cpuid; 88*9338Srafael.vanoni@sun.com int max, cpus_conf; 89*9338Srafael.vanoni@sun.com uint_t ncpus = 0; 90*9338Srafael.vanoni@sun.com 91*9338Srafael.vanoni@sun.com max = sysconf(_SC_CPUID_MAX); 92*9338Srafael.vanoni@sun.com cpus_conf = sysconf(_SC_NPROCESSORS_CONF); 93*9338Srafael.vanoni@sun.com 94*9338Srafael.vanoni@sun.com /* Fall back to one CPU if any of the sysconf calls above failed */ 95*9338Srafael.vanoni@sun.com if (max == -1 || cpus_conf == -1) { 96*9338Srafael.vanoni@sun.com max = cpus_conf = 1; 97*9338Srafael.vanoni@sun.com } 98*9338Srafael.vanoni@sun.com 99*9338Srafael.vanoni@sun.com if ((g_cpu_table = malloc(cpus_conf * sizeof (processorid_t))) == NULL) 100*9338Srafael.vanoni@sun.com return (0); 101*9338Srafael.vanoni@sun.com 102*9338Srafael.vanoni@sun.com for (cpuid = 0; cpuid < max; cpuid++) { 103*9338Srafael.vanoni@sun.com if (p_online(cpuid, P_STATUS) != -1) { 104*9338Srafael.vanoni@sun.com g_cpu_table[ncpus] = cpuid; 105*9338Srafael.vanoni@sun.com ncpus++; 106*9338Srafael.vanoni@sun.com } 107*9338Srafael.vanoni@sun.com } 108*9338Srafael.vanoni@sun.com return (ncpus); 109*9338Srafael.vanoni@sun.com } 110*9338Srafael.vanoni@sun.com 111*9338Srafael.vanoni@sun.com void 112*9338Srafael.vanoni@sun.com usage(void) 113*9338Srafael.vanoni@sun.com { 114*9338Srafael.vanoni@sun.com (void) fprintf(stderr, "%s %s\n\n", TITLE, COPYRIGHT_INTEL); 115*9338Srafael.vanoni@sun.com (void) fprintf(stderr, "Usage: powertop [option]\n"); 116*9338Srafael.vanoni@sun.com (void) fprintf(stderr, " -d, --dump [count] Read wakeups count " 117*9338Srafael.vanoni@sun.com "times and print list of top offenders\n"); 118*9338Srafael.vanoni@sun.com (void) fprintf(stderr, " -t, --time [interval] Default time to gather " 119*9338Srafael.vanoni@sun.com "data in seconds [1-100s]\n"); 120*9338Srafael.vanoni@sun.com (void) fprintf(stderr, " -v, --verbose Verbose mode, reports " 121*9338Srafael.vanoni@sun.com "kernel cyclic activity\n"); 122*9338Srafael.vanoni@sun.com (void) fprintf(stderr, " -c, --cpu [CPU] Only observe a specific" 123*9338Srafael.vanoni@sun.com " CPU\n"); 124*9338Srafael.vanoni@sun.com (void) fprintf(stderr, " -h, --help Show this help " 125*9338Srafael.vanoni@sun.com "message\n"); 126*9338Srafael.vanoni@sun.com 127*9338Srafael.vanoni@sun.com exit(EXIT_USAGE); 128*9338Srafael.vanoni@sun.com } 129*9338Srafael.vanoni@sun.com 130*9338Srafael.vanoni@sun.com int 131*9338Srafael.vanoni@sun.com get_bit_depth(void) 132*9338Srafael.vanoni@sun.com { 133*9338Srafael.vanoni@sun.com /* 134*9338Srafael.vanoni@sun.com * This little routine was derived from isainfo.c to look up 135*9338Srafael.vanoni@sun.com * the system's bit depth. It feeds a 10 byte long buffer to 136*9338Srafael.vanoni@sun.com * sysinfo (we only need the first word, sysinfo truncates and 137*9338Srafael.vanoni@sun.com * \0 terminates the rest) from which we figure out which isa 138*9338Srafael.vanoni@sun.com * we're running on. 139*9338Srafael.vanoni@sun.com */ 140*9338Srafael.vanoni@sun.com char buf[BIT_DEPTH_BUF]; 141*9338Srafael.vanoni@sun.com 142*9338Srafael.vanoni@sun.com if (sysinfo(SI_ARCHITECTURE_64, buf, BIT_DEPTH_BUF) == -1) 143*9338Srafael.vanoni@sun.com if (sysinfo(SI_ARCHITECTURE_32, buf, BIT_DEPTH_BUF) == -1) 144*9338Srafael.vanoni@sun.com return (-2); 145*9338Srafael.vanoni@sun.com 146*9338Srafael.vanoni@sun.com if (strcmp(buf, "sparc") == 0 || strcmp(buf, "i386") == 0) 147*9338Srafael.vanoni@sun.com return (32); 148*9338Srafael.vanoni@sun.com 149*9338Srafael.vanoni@sun.com if (strcmp(buf, "sparcv9") == 0 || strcmp(buf, "amd64") == 0) 150*9338Srafael.vanoni@sun.com return (64); 151*9338Srafael.vanoni@sun.com 152*9338Srafael.vanoni@sun.com return (-3); 153*9338Srafael.vanoni@sun.com } 154*9338Srafael.vanoni@sun.com 155*9338Srafael.vanoni@sun.com /* 156*9338Srafael.vanoni@sun.com * Simple integer comparison routine for the event report qsort(3C). 157*9338Srafael.vanoni@sun.com */ 158*9338Srafael.vanoni@sun.com int 159*9338Srafael.vanoni@sun.com event_compare(const void *p1, const void *p2) 160*9338Srafael.vanoni@sun.com { 161*9338Srafael.vanoni@sun.com event_info_t i = *((event_info_t *)p1); 162*9338Srafael.vanoni@sun.com event_info_t j = *((event_info_t *)p2); 163*9338Srafael.vanoni@sun.com 164*9338Srafael.vanoni@sun.com if (i.total_count > j.total_count) 165*9338Srafael.vanoni@sun.com return (-1); 166*9338Srafael.vanoni@sun.com 167*9338Srafael.vanoni@sun.com if (i.total_count < j.total_count) 168*9338Srafael.vanoni@sun.com return (1); 169*9338Srafael.vanoni@sun.com 170*9338Srafael.vanoni@sun.com return (0); 171*9338Srafael.vanoni@sun.com } 172