diff options
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 75 |
1 files changed, 30 insertions, 45 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 0bf2e8f9af57..593ff25006de 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | #include "util/thread.h" | 25 | #include "util/thread.h" |
| 26 | #include "util/sort.h" | 26 | #include "util/sort.h" |
| 27 | #include "util/hist.h" | 27 | #include "util/hist.h" |
| 28 | #include "util/data_map.h" | 28 | #include "util/session.h" |
| 29 | 29 | ||
| 30 | static char const *input_name = "perf.data"; | 30 | static char const *input_name = "perf.data"; |
| 31 | 31 | ||
| @@ -51,11 +51,6 @@ struct sym_priv { | |||
| 51 | struct sym_ext *ext; | 51 | struct sym_ext *ext; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | static struct symbol_conf symbol_conf = { | ||
| 55 | .priv_size = sizeof(struct sym_priv), | ||
| 56 | .try_vmlinux_path = true, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static const char *sym_hist_filter; | 54 | static const char *sym_hist_filter; |
| 60 | 55 | ||
| 61 | static int symbol_filter(struct map *map __used, struct symbol *sym) | 56 | static int symbol_filter(struct map *map __used, struct symbol *sym) |
| @@ -121,30 +116,32 @@ static void hist_hit(struct hist_entry *he, u64 ip) | |||
| 121 | h->ip[offset]); | 116 | h->ip[offset]); |
| 122 | } | 117 | } |
| 123 | 118 | ||
| 124 | static int hist_entry__add(struct addr_location *al, u64 count) | 119 | static int perf_session__add_hist_entry(struct perf_session *self, |
| 120 | struct addr_location *al, u64 count) | ||
| 125 | { | 121 | { |
| 126 | bool hit; | 122 | bool hit; |
| 127 | struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit); | 123 | struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL, |
| 124 | count, &hit); | ||
| 128 | if (he == NULL) | 125 | if (he == NULL) |
| 129 | return -ENOMEM; | 126 | return -ENOMEM; |
| 130 | hist_hit(he, al->addr); | 127 | hist_hit(he, al->addr); |
| 131 | return 0; | 128 | return 0; |
| 132 | } | 129 | } |
| 133 | 130 | ||
| 134 | static int process_sample_event(event_t *event) | 131 | static int process_sample_event(event_t *event, struct perf_session *session) |
| 135 | { | 132 | { |
| 136 | struct addr_location al; | 133 | struct addr_location al; |
| 137 | 134 | ||
| 138 | dump_printf("(IP, %d): %d: %p\n", event->header.misc, | 135 | dump_printf("(IP, %d): %d: %p\n", event->header.misc, |
| 139 | event->ip.pid, (void *)(long)event->ip.ip); | 136 | event->ip.pid, (void *)(long)event->ip.ip); |
| 140 | 137 | ||
| 141 | if (event__preprocess_sample(event, &al, symbol_filter) < 0) { | 138 | if (event__preprocess_sample(event, session, &al, symbol_filter) < 0) { |
| 142 | fprintf(stderr, "problem processing %d event, skipping it.\n", | 139 | fprintf(stderr, "problem processing %d event, skipping it.\n", |
| 143 | event->header.type); | 140 | event->header.type); |
| 144 | return -1; | 141 | return -1; |
| 145 | } | 142 | } |
| 146 | 143 | ||
| 147 | if (hist_entry__add(&al, 1)) { | 144 | if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) { |
| 148 | fprintf(stderr, "problem incrementing symbol count, " | 145 | fprintf(stderr, "problem incrementing symbol count, " |
| 149 | "skipping event\n"); | 146 | "skipping event\n"); |
| 150 | return -1; | 147 | return -1; |
| @@ -428,11 +425,11 @@ static void annotate_sym(struct hist_entry *he) | |||
| 428 | free_source_line(he, len); | 425 | free_source_line(he, len); |
| 429 | } | 426 | } |
| 430 | 427 | ||
| 431 | static void find_annotations(void) | 428 | static void perf_session__find_annotations(struct perf_session *self) |
| 432 | { | 429 | { |
| 433 | struct rb_node *nd; | 430 | struct rb_node *nd; |
| 434 | 431 | ||
| 435 | for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) { | 432 | for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { |
| 436 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); | 433 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); |
| 437 | struct sym_priv *priv; | 434 | struct sym_priv *priv; |
| 438 | 435 | ||
| @@ -453,7 +450,7 @@ static void find_annotations(void) | |||
| 453 | } | 450 | } |
| 454 | } | 451 | } |
| 455 | 452 | ||
| 456 | static struct perf_file_handler file_handler = { | 453 | static struct perf_event_ops event_ops = { |
| 457 | .process_sample_event = process_sample_event, | 454 | .process_sample_event = process_sample_event, |
| 458 | .process_mmap_event = event__process_mmap, | 455 | .process_mmap_event = event__process_mmap, |
| 459 | .process_comm_event = event__process_comm, | 456 | .process_comm_event = event__process_comm, |
| @@ -462,33 +459,33 @@ static struct perf_file_handler file_handler = { | |||
| 462 | 459 | ||
| 463 | static int __cmd_annotate(void) | 460 | static int __cmd_annotate(void) |
| 464 | { | 461 | { |
| 465 | struct perf_header *header; | ||
| 466 | struct thread *idle; | ||
| 467 | int ret; | 462 | int ret; |
| 463 | struct perf_session *session; | ||
| 468 | 464 | ||
| 469 | idle = register_idle_thread(); | 465 | session = perf_session__new(input_name, O_RDONLY, force); |
| 470 | register_perf_file_handler(&file_handler); | 466 | if (session == NULL) |
| 467 | return -ENOMEM; | ||
| 471 | 468 | ||
| 472 | ret = mmap_dispatch_perf_file(&header, input_name, 0, 0, | 469 | ret = perf_session__process_events(session, &event_ops); |
| 473 | &event__cwdlen, &event__cwd); | ||
| 474 | if (ret) | 470 | if (ret) |
| 475 | return ret; | 471 | goto out_delete; |
| 476 | 472 | ||
| 477 | if (dump_trace) { | 473 | if (dump_trace) { |
| 478 | event__print_totals(); | 474 | event__print_totals(); |
| 479 | return 0; | 475 | goto out_delete; |
| 480 | } | 476 | } |
| 481 | 477 | ||
| 482 | if (verbose > 3) | 478 | if (verbose > 3) |
| 483 | threads__fprintf(stdout); | 479 | perf_session__fprintf(session, stdout); |
| 484 | 480 | ||
| 485 | if (verbose > 2) | 481 | if (verbose > 2) |
| 486 | dsos__fprintf(stdout); | 482 | dsos__fprintf(stdout); |
| 487 | 483 | ||
| 488 | collapse__resort(); | 484 | perf_session__collapse_resort(session); |
| 489 | output__resort(event__total[0]); | 485 | perf_session__output_resort(session, session->event_total[0]); |
| 490 | 486 | perf_session__find_annotations(session); | |
| 491 | find_annotations(); | 487 | out_delete: |
| 488 | perf_session__delete(session); | ||
| 492 | 489 | ||
| 493 | return ret; | 490 | return ret; |
| 494 | } | 491 | } |
| @@ -519,29 +516,17 @@ static const struct option options[] = { | |||
| 519 | OPT_END() | 516 | OPT_END() |
| 520 | }; | 517 | }; |
| 521 | 518 | ||
| 522 | static void setup_sorting(void) | 519 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) |
| 523 | { | 520 | { |
| 524 | char *tmp, *tok, *str = strdup(sort_order); | 521 | argc = parse_options(argc, argv, options, annotate_usage, 0); |
| 525 | |||
| 526 | for (tok = strtok_r(str, ", ", &tmp); | ||
| 527 | tok; tok = strtok_r(NULL, ", ", &tmp)) { | ||
| 528 | if (sort_dimension__add(tok) < 0) { | ||
| 529 | error("Unknown --sort key: `%s'", tok); | ||
| 530 | usage_with_options(annotate_usage, options); | ||
| 531 | } | ||
| 532 | } | ||
| 533 | 522 | ||
| 534 | free(str); | 523 | symbol_conf.priv_size = sizeof(struct sym_priv); |
| 535 | } | 524 | symbol_conf.try_vmlinux_path = true; |
| 536 | 525 | ||
| 537 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) | 526 | if (symbol__init() < 0) |
| 538 | { | ||
| 539 | if (symbol__init(&symbol_conf) < 0) | ||
| 540 | return -1; | 527 | return -1; |
| 541 | 528 | ||
| 542 | argc = parse_options(argc, argv, options, annotate_usage, 0); | 529 | setup_sorting(annotate_usage, options); |
| 543 | |||
| 544 | setup_sorting(); | ||
| 545 | 530 | ||
| 546 | if (argc) { | 531 | if (argc) { |
| 547 | /* | 532 | /* |
