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 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 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 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 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 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 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