Print this page
5218 posix definition of NULL
correct unistd.h and iso/stddef_iso.h
update gate source affected
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/powertop/common/powertop.c
+++ new/usr/src/cmd/powertop/common/powertop.c
1 1 /*
2 2 * Copyright 2009, Intel Corporation
3 3 * Copyright 2009, Sun Microsystems, Inc
4 4 *
5 5 * This file is part of PowerTOP
6 6 *
7 7 * This program file is free software; you can redistribute it and/or modify it
8 8 * under the terms of the GNU General Public License as published by the
9 9 * Free Software Foundation; version 2 of the License.
10 10 *
11 11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * for more details.
15 15 *
16 16 * You should have received a copy of the GNU General Public License
17 17 * along with this program in a file named COPYING; if not, write to the
18 18 * Free Software Foundation, Inc.,
19 19 * 51 Franklin Street, Fifth Floor,
20 20 * Boston, MA 02110-1301 USA
21 21 *
22 22 * Authors:
23 23 * Arjan van de Ven <arjan@linux.intel.com>
24 24 * Eric C Saxe <eric.saxe@sun.com>
25 25 * Aubrey Li <aubrey.li@intel.com>
26 26 */
27 27
28 28 /*
29 29 * GPL Disclaimer
30 30 *
31 31 * For the avoidance of doubt, except that if any license choice other
32 32 * than GPL or LGPL is available it will apply instead, Sun elects to
33 33 * use only the General Public License version 2 (GPLv2) at this time
34 34 * for any software where a choice of GPL license versions is made
35 35 * available with the language indicating that GPLv2 or any later
36 36 * version may be used, or where a choice of which version of the GPL
37 37 * is applied is otherwise unspecified.
38 38 */
39 39
40 40 #include <getopt.h>
41 41 #include <unistd.h>
42 42 #include <stdio.h>
43 43 #include <stdlib.h>
44 44 #include <signal.h>
45 45 #include <string.h>
46 46 #include <ctype.h>
47 47 #include <poll.h>
48 48 #include "powertop.h"
49 49
50 50 /*
51 51 * Global variables, see powertop.h for comments and extern declarations.
52 52 * These are ordered by type, grouped by usage.
53 53 */
54 54 int g_bit_depth;
55 55 int g_total_events, g_top_events;
56 56 int g_npstates, g_max_cstate, g_longest_cstate;
57 57 uint_t g_features;
58 58 uint_t g_ncpus;
59 59 uint_t g_ncpus_observed;
60 60
61 61 processorid_t *g_cpu_table;
62 62
63 63 double g_interval_length;
64 64 hrtime_t g_total_c_time;
65 65
66 66 uchar_t g_op_mode;
67 67 boolean_t g_gui;
68 68 uint_t g_observed_cpu;
69 69
70 70 event_info_t g_event_info[EVENT_NUM_MAX];
71 71 state_info_t g_cstate_info[NSTATES];
72 72 freq_state_info_t g_pstate_info[NSTATES];
73 73 cpu_power_info_t *g_cpu_power_states;
74 74
75 75 boolean_t g_turbo_supported;
76 76 boolean_t g_sig_resize;
77 77
78 78 uint_t g_argc;
79 79 char **g_argv;
80 80
81 81 char *optarg;
82 82
83 83 static const int true = 1;
84 84
85 85 void
86 86 pt_sig_handler(int sig)
87 87 {
88 88 switch (sig) {
89 89 case SIGWINCH:
90 90 g_sig_resize = B_TRUE;
91 91 break;
92 92 }
93 93 }
94 94
95 95 int
96 96 main(int argc, char **argv)
97 97 {
98 98 double interval, interval_usr;
99 99 hrtime_t interval_start;
100 100 int index2 = 0, c, dump_count = 0;
101 101 char *endptr, key;
102 102 boolean_t root_user = B_FALSE;
103 103 struct pollfd pollset;
104 104
105 105 static struct option opts[] = {
106 106 { "dump", 1, NULL, 'd' },
107 107 { "time", 1, NULL, 't' },
108 108 { "help", 0, NULL, 'h' },
109 109 { "cpu", 1, NULL, 'c' },
110 110 { "verbose", 0, NULL, 'v' },
111 111 { 0, 0, NULL, 0 }
112 112 };
113 113
114 114 pt_set_progname(argv[0]);
115 115
116 116 /*
117 117 * Enumerate the system's CPUs, populate cpu_table, g_ncpus
118 118 */
119 119 if ((g_ncpus = g_ncpus_observed = pt_enumerate_cpus()) == 0)
120 120 exit(EXIT_FAILURE);
121 121
122 122 if ((g_bit_depth = pt_get_bit_depth()) < 0)
123 123 exit(EXIT_FAILURE);
124 124
125 125 g_features = 0;
126 126 interval = interval_usr = INTERVAL_DEFAULT;
127 127 g_op_mode = PT_MODE_DEFAULT;
128 128 g_max_cstate = 0;
129 129 g_argv = NULL;
130 130 g_argc = 0;
131 131 g_observed_cpu = 0;
132 132 g_turbo_supported = B_FALSE;
133 133 g_sig_resize = B_FALSE;
134 134 g_curr_sugg = NULL;
135 135
136 136 while ((c = getopt_long(argc, argv, "d:t:hvc:", opts, &index2))
137 137 != EOF) {
138 138 if (c == -1)
139 139 break;
140 140
141 141 switch (c) {
↓ open down ↓ |
141 lines elided |
↑ open up ↑ |
142 142 case 'd':
143 143 if (PT_ON_DUMP) {
144 144 pt_usage();
145 145 exit(EXIT_USAGE);
146 146 }
147 147
148 148 g_op_mode |= PT_MODE_DUMP;
149 149 g_gui = B_FALSE;
150 150 dump_count = (int)strtod(optarg, &endptr);
151 151
152 - if (dump_count <= 0 || *endptr != NULL) {
152 + if (dump_count <= 0 || *endptr != '\0') {
153 153 pt_usage();
154 154 exit(EXIT_USAGE);
155 155 }
156 156
157 157 break;
158 158 case 't':
159 159 if (PT_ON_TIME) {
160 160 pt_usage();
161 161 exit(EXIT_USAGE);
162 162 }
163 163
164 164 g_op_mode |= PT_MODE_TIME;
165 165 interval = interval_usr = (double)strtod(optarg,
166 166 &endptr);
167 167
168 - if (*endptr != NULL || interval < 1 ||
168 + if (*endptr != '\0' || interval < 1 ||
169 169 interval > INTERVAL_MAX) {
170 170 pt_usage();
171 171 exit(EXIT_USAGE);
172 172 }
173 173
174 174 break;
175 175 case 'v':
176 176 if (PT_ON_CPU || PT_ON_VERBOSE) {
177 177 pt_usage();
178 178 exit(EXIT_USAGE);
179 179 }
180 180
181 181 g_op_mode |= PT_MODE_VERBOSE;
182 182 break;
183 183 case 'c':
184 184 if (PT_ON_CPU || PT_ON_VERBOSE) {
185 185 pt_usage();
186 186 exit(EXIT_USAGE);
187 187 }
188 188
189 189 g_op_mode |= PT_MODE_CPU;
190 190 g_observed_cpu = (uint_t)strtod(optarg, &endptr);
191 191
192 192 if (g_observed_cpu >= g_ncpus) {
193 193 pt_usage();
194 194 exit(EXIT_USAGE);
195 195 }
196 196
197 197 g_argc = 1;
198 198 g_ncpus_observed = 1;
199 199
200 200 if ((g_argv = malloc(sizeof (char *))) == NULL)
201 201 return (EXIT_FAILURE);
202 202
203 203 if ((*g_argv = malloc(sizeof (char) * 5)) == NULL)
204 204 return (EXIT_FAILURE);
205 205
206 206 (void) snprintf(*g_argv, 5, "%d\0", g_observed_cpu);
207 207 break;
208 208 case 'h':
209 209 pt_usage();
210 210 exit(EXIT_SUCCESS);
211 211 default:
212 212 pt_usage();
213 213 exit(EXIT_USAGE);
214 214 }
215 215 }
216 216
217 217 if (optind < argc) {
218 218 pt_usage();
219 219 exit(EXIT_USAGE);
220 220 }
221 221
222 222 (void) printf("%s %s\n\n", TITLE, COPYRIGHT_INTEL);
223 223
224 224 (void) printf("Collecting data for %.2f second(s) \n",
225 225 (float)interval);
226 226
227 227 /* Prepare P-state statistics */
228 228 if (pt_cpufreq_stat_prepare() == 0)
229 229 g_features |= FEATURE_PSTATE;
230 230
231 231 /* Prepare C-state statistics */
232 232 if (pt_cpuidle_stat_prepare() == 0)
233 233 g_features |= FEATURE_CSTATE;
234 234 else
235 235 /*
236 236 * PowerTop was unable to run a DTrace program,
237 237 * most likely for lack of permissions.
238 238 */
239 239 exit(EXIT_FAILURE);
240 240
241 241 /* Prepare event statistics */
242 242 if (pt_events_stat_prepare() != -1)
243 243 g_features |= FEATURE_EVENTS;
244 244
245 245 /*
246 246 * If the system is running on battery, find out what's
247 247 * the kstat module for it
248 248 */
249 249 pt_battery_mod_lookup();
250 250
251 251 /* Prepare turbo statistics */
252 252 if (pt_turbo_stat_prepare() == 0)
253 253 g_features |= FEATURE_TURBO;
254 254
255 255 /*
256 256 * Initialize the display.
257 257 */
258 258 if (!PT_ON_DUMP) {
259 259 pt_display_init_curses();
260 260 pt_display_setup(B_FALSE);
261 261 (void) signal(SIGWINCH, pt_sig_handler);
262 262
263 263 pt_display_title_bar();
264 264 pt_display_status_bar();
265 265
266 266 g_gui = B_TRUE;
267 267 pollset.fd = STDIN_FILENO;
268 268 pollset.events = POLLIN;
269 269 }
270 270
271 271 /*
272 272 * Installs the initial suggestions, running as root and turning CPU
273 273 * power management ON.
274 274 */
275 275 if (geteuid() != 0) {
276 276 pt_sugg_as_root();
277 277 } else {
278 278 root_user = B_TRUE;
279 279 pt_cpufreq_suggest();
280 280 }
281 281
282 282 while (true) {
283 283 key = 0;
284 284
285 285 if (g_sig_resize)
286 286 pt_display_resize();
287 287
288 288 interval_start = gethrtime();
289 289
290 290 if (!PT_ON_DUMP) {
291 291 if (poll(&pollset, (nfds_t)1,
292 292 (int)(interval * MILLISEC)) > 0)
293 293 (void) read(STDIN_FILENO, &key, 1);
294 294 } else {
295 295 (void) sleep((int)interval);
296 296 }
297 297
298 298 g_interval_length = (double)(gethrtime() - interval_start)
299 299 /NANOSEC;
300 300
301 301 g_top_events = 0;
302 302 g_total_events = 0;
303 303
304 304 (void) memset(g_event_info, 0,
305 305 EVENT_NUM_MAX * sizeof (event_info_t));
306 306 (void) memset(g_cstate_info, 0,
307 307 NSTATES * sizeof (state_info_t));
308 308
309 309 /* Collect idle state transition stats */
310 310 if (g_features & FEATURE_CSTATE &&
311 311 pt_cpuidle_stat_collect(g_interval_length) < 0) {
312 312 /* Reinitialize C-state statistics */
313 313 if (pt_cpuidle_stat_prepare() != 0)
314 314 exit(EXIT_FAILURE);
315 315
316 316 continue;
317 317 }
318 318
319 319 /* Collect frequency change stats */
320 320 if (g_features & FEATURE_PSTATE &&
321 321 pt_cpufreq_stat_collect(g_interval_length) < 0) {
322 322 /* Reinitialize P-state statistics */
323 323 if (pt_cpufreq_stat_prepare() != 0)
324 324 exit(EXIT_FAILURE);
325 325
326 326 continue;
327 327 }
328 328
329 329 /* Collect event statistics */
330 330 if (g_features & FEATURE_EVENTS &&
331 331 pt_events_stat_collect() < 0) {
332 332 /* Reinitialize event statistics */
333 333 if (pt_events_stat_prepare() != 0)
334 334 exit(EXIT_FAILURE);
335 335
336 336 continue;
337 337 }
338 338
339 339 /* Collect turbo statistics */
340 340 if (g_features & FEATURE_TURBO &&
341 341 pt_turbo_stat_collect() < 0)
342 342 exit(EXIT_FAILURE);
343 343
344 344 /* Show CPU power states */
345 345 pt_display_states();
346 346
347 347 /* Show wakeups events affecting PM */
348 348 if (g_features & FEATURE_EVENTS) {
349 349 pt_display_wakeups(g_interval_length);
350 350 pt_display_events(g_interval_length);
351 351 }
352 352
353 353 pt_battery_print();
354 354
355 355 if (key && !PT_ON_DUMP) {
356 356 switch (toupper(key)) {
357 357 case 'Q':
358 358 exit(EXIT_SUCCESS);
359 359 break;
360 360
361 361 case 'R':
362 362 interval = 3;
363 363 break;
364 364 }
365 365
366 366 /*
367 367 * Check if the user has activated the current
368 368 * suggestion.
369 369 */
370 370 if (g_curr_sugg != NULL &&
371 371 toupper(key) == g_curr_sugg->key &&
372 372 g_curr_sugg->func)
373 373 g_curr_sugg->func();
374 374 }
375 375
376 376 if (dump_count)
377 377 dump_count--;
378 378
379 379 /* Exits if user requested a dump */
380 380 if (PT_ON_DUMP && !dump_count)
381 381 exit(EXIT_SUCCESS);
382 382
383 383 /* No key pressed, will suggest something */
384 384 if (!key && !dump_count)
385 385 pt_sugg_pick();
386 386
387 387 /* Refresh display */
388 388 if (!PT_ON_DUMP)
389 389 pt_display_update();
390 390
391 391 if (root_user)
392 392 pt_cpufreq_suggest();
393 393
394 394 /*
395 395 * Update the interval based on how long the CPU was in the
396 396 * longest c-state during the last snapshot. If the user
397 397 * specified an interval we skip this bit and keep it fixed.
398 398 */
399 399 if (g_features & FEATURE_CSTATE && !PT_ON_TIME &&
400 400 g_longest_cstate > 0 &&
401 401 g_cstate_info[g_longest_cstate].events > 0) {
402 402 double deep_idle_res = (((double)
403 403 g_cstate_info[g_longest_cstate].total_time/MICROSEC
404 404 /g_ncpus)/g_cstate_info[g_longest_cstate].events);
405 405
406 406 if (deep_idle_res < INTERVAL_DEFAULT ||
407 407 (g_total_events/interval) < 1)
408 408 interval = INTERVAL_DEFAULT;
409 409 else
410 410 interval = INTERVAL_UPDATE(deep_idle_res);
411 411 } else {
412 412 /*
413 413 * Restore interval after a refresh.
414 414 */
415 415 if (key)
416 416 interval = interval_usr;
417 417 }
418 418 }
419 419
420 420 return (EXIT_SUCCESS);
421 421 }
↓ open down ↓ |
243 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX