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 char *kstat_batt_mod[3] = {"NULL", "battery", "acpi_drv"}; 55 uint_t kstat_batt_idx; 56 57 void 58 pt_set_progname(char *name) 59 { 60 progname = basename(name); 61 } 62 63 /*PRINTFLIKE1*/ 64 void 65 pt_error(char *format, ...) 66 { 67 int err = errno; 68 va_list alist; 69 70 if (gui) 71 return; 72 73 if (progname != NULL) 74 (void) fprintf(stderr, PROG_FMT, progname); 75 76 va_start(alist, format); 77 (void) vfprintf(stderr, format, alist); 78 va_end(alist); 79 80 if (strchr(format, '\n') == NULL) 81 (void) fprintf(stderr, gettext(ERR_FMT), strerror(err)); 82 } 83 84 void 85 enumerate_cpus(void) 86 { 87 int cpuid; 88 int ncpus = 0; 89 int max, cpus_conf; 90 91 max = sysconf(_SC_CPUID_MAX); 92 cpus_conf = sysconf(_SC_NPROCESSORS_CONF); 93 cpu_table = malloc(cpus_conf * sizeof (processorid_t)); 94 95 for (cpuid = 0; cpuid < max; cpuid++) { 96 if (p_online(cpuid, P_STATUS) != -1) { 97 cpu_table[ncpus] = cpuid; 98 ncpus++; 99 } 100 } 101 g_ncpus = ncpus; 102 } 103 104 void 105 usage(void) 106 { 107 (void) fprintf(stderr, "%s (C) 2009 Intel Corporation\n\n", TITLE); 108 (void) fprintf(stderr, "Usage: powertop [option]\n"); 109 (void) fprintf(stderr, " -d, --dump [count] Read wakeups count " 110 "times and print list of top offenders\n"); 111 (void) fprintf(stderr, " -t, --time [interval] Default time to gather " 112 "data in seconds [1-100s]\n"); 113 (void) fprintf(stderr, " -v, --verbose Verbose mode, reports " 114 "kernel cyclic activity\n"); 115 (void) fprintf(stderr, " -h, --help Show this help " 116 "message\n"); 117 118 exit(EXIT_USAGE); 119 } 120 121 int 122 get_bit_depth(void) 123 { 124 /* 125 * This little routine was derived from isainfo.c to look up 126 * the system's bit depth. It feeds a 10 byte long buffer to 127 * sysinfo (we only need the first word, sysinfo truncates and 128 * \0 terminates the rest) from which we figure out which isa 129 * we're running on. 130 */ 131 char buf[BIT_DEPTH_BUF]; 132 133 if (sysinfo(SI_ARCHITECTURE_64, buf, BIT_DEPTH_BUF) == -1) 134 if (sysinfo(SI_ARCHITECTURE_32, buf, BIT_DEPTH_BUF) == -1) 135 return (-2); 136 137 if (strcmp(buf, "sparc") == 0 || strcmp(buf, "i386") == 0) 138 return (32); 139 140 if (strcmp(buf, "sparcv9") == 0 || strcmp(buf, "amd64") == 0) 141 return (64); 142 143 return (-3); 144 } 145 146 /* 147 * Checks if the kstat module for battery information is present and 148 * whether it's called 'battery' or 'acpi_drv' 149 */ 150 void 151 battery_mod_lookup(void) 152 { 153 kstat_ctl_t *kc = kstat_open(); 154 155 if (kstat_lookup(kc, kstat_batt_mod[1], 0, NULL)) 156 kstat_batt_idx = 1; 157 else 158 if (kstat_lookup(kc, kstat_batt_mod[2], 0, NULL)) 159 kstat_batt_idx = 2; 160 else 161 kstat_batt_idx = 0; 162 163 (void) kstat_close(kc); 164 } 165 166 /* 167 * Simple integer comparison routine for the event report qsort(3C). 168 */ 169 int 170 event_compare(const void *p1, const void *p2) 171 { 172 event_info_t i = *((event_info_t *)p1); 173 event_info_t j = *((event_info_t *)p2); 174 175 if (i.total_count > j.total_count) 176 return (-1); 177 178 if (i.total_count < j.total_count) 179 return (1); 180 181 return (0); 182 } 183