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