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