xref: /illumos-gate/usr/src/cmd/powertop/common/util.c (revision 88681574)
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