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
50static char 	PROG_FMT[] = "%s: ";
51static char 	ERR_FMT[] = ": %s";
52static char 	*progname;
53
54void
55pt_set_progname(char *name)
56{
57	progname = basename(name);
58}
59
60/*PRINTFLIKE1*/
61void
62pt_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, ERR_FMT, strerror(err));
79}
80
81/*
82 * Returns the number of online CPUs.
83 */
84uint_t
85pt_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
111void
112pt_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-30s]\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
128int
129pt_get_bit_depth(void)
130{
131	/*
132	 * This little routine was derived from isainfo.c to look up
133	 * the system's bit depth. It feeds a 10 byte long buffer to
134	 * sysinfo (we only need the first word, sysinfo truncates and
135	 * \0 terminates the rest) from which we figure out which isa
136	 * we're running on.
137	 */
138	char	buf[BIT_DEPTH_BUF];
139
140	if (sysinfo(SI_ARCHITECTURE_64, buf, BIT_DEPTH_BUF) == -1)
141		if (sysinfo(SI_ARCHITECTURE_32, buf, BIT_DEPTH_BUF) == -1)
142			return (-2);
143
144	if (strcmp(buf, "sparc") == 0 || strcmp(buf, "i386") == 0)
145		return (32);
146
147	if (strcmp(buf, "sparcv9") == 0 || strcmp(buf, "amd64") == 0)
148		return (64);
149
150	return (-3);
151}
152
153/*
154 * Simple integer comparison routine for the event report qsort(3C).
155 */
156int
157pt_event_compare(const void *p1, const void *p2)
158{
159	event_info_t i = *((event_info_t *)p1);
160	event_info_t j = *((event_info_t *)p2);
161
162	if (i.total_count > j.total_count)
163		return (-1);
164
165	if (i.total_count < j.total_count)
166		return (1);
167
168	return (0);
169}
170