aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-01-11 17:56:53 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-01-22 16:56:28 -0500
commit361c99a661a78ed22264649440e87fe4fe8da1f2 (patch)
treea60bc86f132608f2d41c800760b41f6f54f8e7af /tools/perf/builtin-top.c
parent00e99a49f6f3a6b5a84ba8bf8f632c9b974bea7a (diff)
perf evsel: Introduce perf_evlist
Killing two more perf wide global variables: nr_counters and evsel_list as a list_head. There are more operations that will need more fields in perf_evlist, like the pollfd for polling all the fds in a list of evsel instances. Use option->value to pass the evsel_list to parse_{events,filters}. LKML-Reference: <new-submission> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c60
1 files changed, 34 insertions, 26 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index b6998e055767..216b62ed4b89 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -21,6 +21,7 @@
21#include "perf.h" 21#include "perf.h"
22 22
23#include "util/color.h" 23#include "util/color.h"
24#include "util/evlist.h"
24#include "util/evsel.h" 25#include "util/evsel.h"
25#include "util/session.h" 26#include "util/session.h"
26#include "util/symbol.h" 27#include "util/symbol.h"
@@ -60,6 +61,8 @@
60 61
61#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 62#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
62 63
64struct perf_evlist *evsel_list;
65
63static bool system_wide = false; 66static bool system_wide = false;
64 67
65static int default_interval = 0; 68static int default_interval = 0;
@@ -267,7 +270,7 @@ static void __zero_source_counters(struct sym_entry *syme)
267 270
268 line = syme->src->lines; 271 line = syme->src->lines;
269 while (line) { 272 while (line) {
270 for (i = 0; i < nr_counters; i++) 273 for (i = 0; i < evsel_list->nr_entries; i++)
271 line->count[i] = 0; 274 line->count[i] = 0;
272 line = line->next; 275 line = line->next;
273 } 276 }
@@ -414,7 +417,7 @@ static double sym_weight(const struct sym_entry *sym)
414 if (!display_weighted) 417 if (!display_weighted)
415 return weight; 418 return weight;
416 419
417 for (counter = 1; counter < nr_counters-1; counter++) 420 for (counter = 1; counter < evsel_list->nr_entries - 1; counter++)
418 weight *= sym->count[counter]; 421 weight *= sym->count[counter];
419 422
420 weight /= (sym->count[counter] + 1); 423 weight /= (sym->count[counter] + 1);
@@ -501,7 +504,7 @@ static void print_sym_table(void)
501 rb_insert_active_sym(&tmp, syme); 504 rb_insert_active_sym(&tmp, syme);
502 sum_ksamples += syme->snap_count; 505 sum_ksamples += syme->snap_count;
503 506
504 for (j = 0; j < nr_counters; j++) 507 for (j = 0; j < evsel_list->nr_entries; j++)
505 syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8; 508 syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8;
506 } else 509 } else
507 list_remove_active_sym(syme); 510 list_remove_active_sym(syme);
@@ -535,9 +538,9 @@ static void print_sym_table(void)
535 esamples_percent); 538 esamples_percent);
536 } 539 }
537 540
538 if (nr_counters == 1 || !display_weighted) { 541 if (evsel_list->nr_entries == 1 || !display_weighted) {
539 struct perf_evsel *first; 542 struct perf_evsel *first;
540 first = list_entry(evsel_list.next, struct perf_evsel, node); 543 first = list_entry(evsel_list->entries.next, struct perf_evsel, node);
541 printf("%" PRIu64, (uint64_t)first->attr.sample_period); 544 printf("%" PRIu64, (uint64_t)first->attr.sample_period);
542 if (freq) 545 if (freq)
543 printf("Hz "); 546 printf("Hz ");
@@ -547,7 +550,7 @@ static void print_sym_table(void)
547 550
548 if (!display_weighted) 551 if (!display_weighted)
549 printf("%s", event_name(sym_evsel)); 552 printf("%s", event_name(sym_evsel));
550 else list_for_each_entry(counter, &evsel_list, node) { 553 else list_for_each_entry(counter, &evsel_list->entries, node) {
551 if (counter->idx) 554 if (counter->idx)
552 printf("/"); 555 printf("/");
553 556
@@ -606,7 +609,7 @@ static void print_sym_table(void)
606 sym_width = winsize.ws_col - dso_width - 29; 609 sym_width = winsize.ws_col - dso_width - 29;
607 } 610 }
608 putchar('\n'); 611 putchar('\n');
609 if (nr_counters == 1) 612 if (evsel_list->nr_entries == 1)
610 printf(" samples pcnt"); 613 printf(" samples pcnt");
611 else 614 else
612 printf(" weight samples pcnt"); 615 printf(" weight samples pcnt");
@@ -615,7 +618,7 @@ static void print_sym_table(void)
615 printf(" RIP "); 618 printf(" RIP ");
616 printf(" %-*.*s DSO\n", sym_width, sym_width, "function"); 619 printf(" %-*.*s DSO\n", sym_width, sym_width, "function");
617 printf(" %s _______ _____", 620 printf(" %s _______ _____",
618 nr_counters == 1 ? " " : "______"); 621 evsel_list->nr_entries == 1 ? " " : "______");
619 if (verbose) 622 if (verbose)
620 printf(" ________________"); 623 printf(" ________________");
621 printf(" %-*.*s", sym_width, sym_width, graph_line); 624 printf(" %-*.*s", sym_width, sym_width, graph_line);
@@ -634,7 +637,7 @@ static void print_sym_table(void)
634 pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / 637 pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
635 sum_ksamples)); 638 sum_ksamples));
636 639
637 if (nr_counters == 1 || !display_weighted) 640 if (evsel_list->nr_entries == 1 || !display_weighted)
638 printf("%20.2f ", syme->weight); 641 printf("%20.2f ", syme->weight);
639 else 642 else
640 printf("%9.1f %10ld ", syme->weight, syme->snap_count); 643 printf("%9.1f %10ld ", syme->weight, syme->snap_count);
@@ -744,7 +747,7 @@ static void print_mapped_keys(void)
744 fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs); 747 fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs);
745 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); 748 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries);
746 749
747 if (nr_counters > 1) 750 if (evsel_list->nr_entries > 1)
748 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_evsel)); 751 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_evsel));
749 752
750 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); 753 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter);
@@ -753,7 +756,7 @@ static void print_mapped_keys(void)
753 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); 756 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
754 fprintf(stdout, "\t[S] stop annotation.\n"); 757 fprintf(stdout, "\t[S] stop annotation.\n");
755 758
756 if (nr_counters > 1) 759 if (evsel_list->nr_entries > 1)
757 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); 760 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0);
758 761
759 fprintf(stdout, 762 fprintf(stdout,
@@ -783,7 +786,7 @@ static int key_mapped(int c)
783 return 1; 786 return 1;
784 case 'E': 787 case 'E':
785 case 'w': 788 case 'w':
786 return nr_counters > 1 ? 1 : 0; 789 return evsel_list->nr_entries > 1 ? 1 : 0;
787 default: 790 default:
788 break; 791 break;
789 } 792 }
@@ -831,22 +834,22 @@ static void handle_keypress(struct perf_session *session, int c)
831 signal(SIGWINCH, SIG_DFL); 834 signal(SIGWINCH, SIG_DFL);
832 break; 835 break;
833 case 'E': 836 case 'E':
834 if (nr_counters > 1) { 837 if (evsel_list->nr_entries > 1) {
835 fprintf(stderr, "\nAvailable events:"); 838 fprintf(stderr, "\nAvailable events:");
836 839
837 list_for_each_entry(sym_evsel, &evsel_list, node) 840 list_for_each_entry(sym_evsel, &evsel_list->entries, node)
838 fprintf(stderr, "\n\t%d %s", sym_evsel->idx, event_name(sym_evsel)); 841 fprintf(stderr, "\n\t%d %s", sym_evsel->idx, event_name(sym_evsel));
839 842
840 prompt_integer(&sym_counter, "Enter details event counter"); 843 prompt_integer(&sym_counter, "Enter details event counter");
841 844
842 if (sym_counter >= nr_counters) { 845 if (sym_counter >= evsel_list->nr_entries) {
843 sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node); 846 sym_evsel = list_entry(evsel_list->entries.next, struct perf_evsel, node);
844 sym_counter = 0; 847 sym_counter = 0;
845 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(sym_evsel)); 848 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(sym_evsel));
846 sleep(1); 849 sleep(1);
847 break; 850 break;
848 } 851 }
849 list_for_each_entry(sym_evsel, &evsel_list, node) 852 list_for_each_entry(sym_evsel, &evsel_list->entries, node)
850 if (sym_evsel->idx == sym_counter) 853 if (sym_evsel->idx == sym_counter)
851 break; 854 break;
852 } else sym_counter = 0; 855 } else sym_counter = 0;
@@ -1198,7 +1201,7 @@ static void perf_session__mmap_read(struct perf_session *self)
1198 int i, thread_index; 1201 int i, thread_index;
1199 1202
1200 for (i = 0; i < cpus->nr; i++) { 1203 for (i = 0; i < cpus->nr; i++) {
1201 list_for_each_entry(counter, &evsel_list, node) { 1204 list_for_each_entry(counter, &evsel_list->entries, node) {
1202 for (thread_index = 0; 1205 for (thread_index = 0;
1203 thread_index < threads->nr; 1206 thread_index < threads->nr;
1204 thread_index++) { 1207 thread_index++) {
@@ -1312,7 +1315,7 @@ static int __cmd_top(void)
1312 1315
1313 for (i = 0; i < cpus->nr; i++) { 1316 for (i = 0; i < cpus->nr; i++) {
1314 group_fd = -1; 1317 group_fd = -1;
1315 list_for_each_entry(counter, &evsel_list, node) 1318 list_for_each_entry(counter, &evsel_list->entries, node)
1316 start_counter(i, counter); 1319 start_counter(i, counter);
1317 } 1320 }
1318 1321
@@ -1354,7 +1357,7 @@ static const char * const top_usage[] = {
1354}; 1357};
1355 1358
1356static const struct option options[] = { 1359static const struct option options[] = {
1357 OPT_CALLBACK('e', "event", NULL, "event", 1360 OPT_CALLBACK('e', "event", &evsel_list, "event",
1358 "event selector. use 'perf list' to list available events", 1361 "event selector. use 'perf list' to list available events",
1359 parse_events), 1362 parse_events),
1360 OPT_INTEGER('c', "count", &default_interval, 1363 OPT_INTEGER('c', "count", &default_interval,
@@ -1404,6 +1407,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1404 struct perf_evsel *pos; 1407 struct perf_evsel *pos;
1405 int status = -ENOMEM; 1408 int status = -ENOMEM;
1406 1409
1410 evsel_list = perf_evlist__new();
1411 if (evsel_list == NULL)
1412 return -ENOMEM;
1413
1407 page_size = sysconf(_SC_PAGE_SIZE); 1414 page_size = sysconf(_SC_PAGE_SIZE);
1408 1415
1409 argc = parse_options(argc, argv, options, top_usage, 0); 1416 argc = parse_options(argc, argv, options, top_usage, 0);
@@ -1431,7 +1438,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1431 cpu_list = NULL; 1438 cpu_list = NULL;
1432 } 1439 }
1433 1440
1434 if (!nr_counters && perf_evsel_list__create_default() < 0) { 1441 if (!evsel_list->nr_entries &&
1442 perf_evlist__add_default(evsel_list) < 0) {
1435 pr_err("Not enough memory for event selector list\n"); 1443 pr_err("Not enough memory for event selector list\n");
1436 return -ENOMEM; 1444 return -ENOMEM;
1437 } 1445 }
@@ -1459,7 +1467,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1459 if (cpus == NULL) 1467 if (cpus == NULL)
1460 usage_with_options(top_usage, options); 1468 usage_with_options(top_usage, options);
1461 1469
1462 list_for_each_entry(pos, &evsel_list, node) { 1470 list_for_each_entry(pos, &evsel_list->entries, node) {
1463 if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 || 1471 if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 ||
1464 perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) 1472 perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
1465 goto out_free_fd; 1473 goto out_free_fd;
@@ -1472,10 +1480,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1472 pos->attr.sample_period = default_interval; 1480 pos->attr.sample_period = default_interval;
1473 } 1481 }
1474 1482
1475 sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node); 1483 sym_evsel = list_entry(evsel_list->entries.next, struct perf_evsel, node);
1476 1484
1477 symbol_conf.priv_size = (sizeof(struct sym_entry) + 1485 symbol_conf.priv_size = (sizeof(struct sym_entry) +
1478 (nr_counters + 1) * sizeof(unsigned long)); 1486 (evsel_list->nr_entries + 1) * sizeof(unsigned long));
1479 1487
1480 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 1488 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1481 if (symbol__init() < 0) 1489 if (symbol__init() < 0)
@@ -1489,9 +1497,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1489 1497
1490 status = __cmd_top(); 1498 status = __cmd_top();
1491out_free_fd: 1499out_free_fd:
1492 list_for_each_entry(pos, &evsel_list, node) 1500 list_for_each_entry(pos, &evsel_list->entries, node)
1493 perf_evsel__free_mmap(pos); 1501 perf_evsel__free_mmap(pos);
1494 perf_evsel_list__delete(); 1502 perf_evlist__delete(evsel_list);
1495 1503
1496 return status; 1504 return status;
1497} 1505}