diff options
Diffstat (limited to 'tools/perf/util/hist.c')
| -rw-r--r-- | tools/perf/util/hist.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 09e09e78cb62..18cf8b321608 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -50,7 +50,8 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
| 50 | p = &(*p)->rb_right; | 50 | p = &(*p)->rb_right; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | he = malloc(sizeof(*he)); | 53 | he = malloc(sizeof(*he) + (symbol_conf.use_callchain ? |
| 54 | sizeof(struct callchain_node) : 0)); | ||
| 54 | if (!he) | 55 | if (!he) |
| 55 | return NULL; | 56 | return NULL; |
| 56 | *he = entry; | 57 | *he = entry; |
| @@ -168,7 +169,7 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root, | |||
| 168 | struct hist_entry *iter; | 169 | struct hist_entry *iter; |
| 169 | 170 | ||
| 170 | if (symbol_conf.use_callchain) | 171 | if (symbol_conf.use_callchain) |
| 171 | callchain_param.sort(&he->sorted_chain, &he->callchain, | 172 | callchain_param.sort(&he->sorted_chain, he->callchain, |
| 172 | min_callchain_hits, &callchain_param); | 173 | min_callchain_hits, &callchain_param); |
| 173 | 174 | ||
| 174 | while (*p != NULL) { | 175 | while (*p != NULL) { |
| @@ -185,12 +186,13 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root, | |||
| 185 | rb_insert_color(&he->rb_node, root); | 186 | rb_insert_color(&he->rb_node, root); |
| 186 | } | 187 | } |
| 187 | 188 | ||
| 188 | void perf_session__output_resort(struct rb_root *hists, u64 total_samples) | 189 | u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples) |
| 189 | { | 190 | { |
| 190 | struct rb_root tmp; | 191 | struct rb_root tmp; |
| 191 | struct rb_node *next; | 192 | struct rb_node *next; |
| 192 | struct hist_entry *n; | 193 | struct hist_entry *n; |
| 193 | u64 min_callchain_hits; | 194 | u64 min_callchain_hits; |
| 195 | u64 nr_hists = 0; | ||
| 194 | 196 | ||
| 195 | min_callchain_hits = | 197 | min_callchain_hits = |
| 196 | total_samples * (callchain_param.min_percent / 100); | 198 | total_samples * (callchain_param.min_percent / 100); |
| @@ -205,9 +207,11 @@ void perf_session__output_resort(struct rb_root *hists, u64 total_samples) | |||
| 205 | rb_erase(&n->rb_node, hists); | 207 | rb_erase(&n->rb_node, hists); |
| 206 | perf_session__insert_output_hist_entry(&tmp, n, | 208 | perf_session__insert_output_hist_entry(&tmp, n, |
| 207 | min_callchain_hits); | 209 | min_callchain_hits); |
| 210 | ++nr_hists; | ||
| 208 | } | 211 | } |
| 209 | 212 | ||
| 210 | *hists = tmp; | 213 | *hists = tmp; |
| 214 | return nr_hists; | ||
| 211 | } | 215 | } |
| 212 | 216 | ||
| 213 | static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) | 217 | static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) |
| @@ -452,16 +456,17 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
| 452 | return ret; | 456 | return ret; |
| 453 | } | 457 | } |
| 454 | 458 | ||
| 455 | size_t hist_entry__fprintf(struct hist_entry *self, | 459 | int hist_entry__snprintf(struct hist_entry *self, |
| 460 | char *s, size_t size, | ||
| 456 | struct perf_session *pair_session, | 461 | struct perf_session *pair_session, |
| 457 | bool show_displacement, | 462 | bool show_displacement, |
| 458 | long displacement, FILE *fp, | 463 | long displacement, bool color, |
| 459 | u64 session_total) | 464 | u64 session_total) |
| 460 | { | 465 | { |
| 461 | struct sort_entry *se; | 466 | struct sort_entry *se; |
| 462 | u64 count, total; | 467 | u64 count, total; |
| 463 | const char *sep = symbol_conf.field_sep; | 468 | const char *sep = symbol_conf.field_sep; |
| 464 | size_t ret; | 469 | int ret; |
| 465 | 470 | ||
| 466 | if (symbol_conf.exclude_other && !self->parent) | 471 | if (symbol_conf.exclude_other && !self->parent) |
| 467 | return 0; | 472 | return 0; |
| @@ -474,17 +479,22 @@ size_t hist_entry__fprintf(struct hist_entry *self, | |||
| 474 | total = session_total; | 479 | total = session_total; |
| 475 | } | 480 | } |
| 476 | 481 | ||
| 477 | if (total) | 482 | if (total) { |
| 478 | ret = percent_color_fprintf(fp, sep ? "%.2f" : " %6.2f%%", | 483 | if (color) |
| 479 | (count * 100.0) / total); | 484 | ret = percent_color_snprintf(s, size, |
| 480 | else | 485 | sep ? "%.2f" : " %6.2f%%", |
| 481 | ret = fprintf(fp, sep ? "%lld" : "%12lld ", count); | 486 | (count * 100.0) / total); |
| 487 | else | ||
| 488 | ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%", | ||
| 489 | (count * 100.0) / total); | ||
| 490 | } else | ||
| 491 | ret = snprintf(s, size, sep ? "%lld" : "%12lld ", count); | ||
| 482 | 492 | ||
| 483 | if (symbol_conf.show_nr_samples) { | 493 | if (symbol_conf.show_nr_samples) { |
| 484 | if (sep) | 494 | if (sep) |
| 485 | ret += fprintf(fp, "%c%lld", *sep, count); | 495 | ret += snprintf(s + ret, size - ret, "%c%lld", *sep, count); |
| 486 | else | 496 | else |
| 487 | ret += fprintf(fp, "%11lld", count); | 497 | ret += snprintf(s + ret, size - ret, "%11lld", count); |
| 488 | } | 498 | } |
| 489 | 499 | ||
| 490 | if (pair_session) { | 500 | if (pair_session) { |
| @@ -504,9 +514,9 @@ size_t hist_entry__fprintf(struct hist_entry *self, | |||
| 504 | snprintf(bf, sizeof(bf), " "); | 514 | snprintf(bf, sizeof(bf), " "); |
| 505 | 515 | ||
| 506 | if (sep) | 516 | if (sep) |
| 507 | ret += fprintf(fp, "%c%s", *sep, bf); | 517 | ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf); |
| 508 | else | 518 | else |
| 509 | ret += fprintf(fp, "%11.11s", bf); | 519 | ret += snprintf(s + ret, size - ret, "%11.11s", bf); |
| 510 | 520 | ||
| 511 | if (show_displacement) { | 521 | if (show_displacement) { |
| 512 | if (displacement) | 522 | if (displacement) |
| @@ -515,9 +525,9 @@ size_t hist_entry__fprintf(struct hist_entry *self, | |||
| 515 | snprintf(bf, sizeof(bf), " "); | 525 | snprintf(bf, sizeof(bf), " "); |
| 516 | 526 | ||
| 517 | if (sep) | 527 | if (sep) |
| 518 | ret += fprintf(fp, "%c%s", *sep, bf); | 528 | ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf); |
| 519 | else | 529 | else |
| 520 | ret += fprintf(fp, "%6.6s", bf); | 530 | ret += snprintf(s + ret, size - ret, "%6.6s", bf); |
| 521 | } | 531 | } |
| 522 | } | 532 | } |
| 523 | 533 | ||
| @@ -525,11 +535,25 @@ size_t hist_entry__fprintf(struct hist_entry *self, | |||
| 525 | if (se->elide) | 535 | if (se->elide) |
| 526 | continue; | 536 | continue; |
| 527 | 537 | ||
| 528 | ret += fprintf(fp, "%s", sep ?: " "); | 538 | ret += snprintf(s + ret, size - ret, "%s", sep ?: " "); |
| 529 | ret += se->print(fp, self, se->width ? *se->width : 0); | 539 | ret += se->snprintf(self, s + ret, size - ret, |
| 540 | se->width ? *se->width : 0); | ||
| 530 | } | 541 | } |
| 531 | 542 | ||
| 532 | return ret + fprintf(fp, "\n"); | 543 | return ret; |
| 544 | } | ||
| 545 | |||
| 546 | int hist_entry__fprintf(struct hist_entry *self, | ||
| 547 | struct perf_session *pair_session, | ||
| 548 | bool show_displacement, | ||
| 549 | long displacement, FILE *fp, | ||
| 550 | u64 session_total) | ||
| 551 | { | ||
| 552 | char bf[512]; | ||
| 553 | hist_entry__snprintf(self, bf, sizeof(bf), pair_session, | ||
| 554 | show_displacement, displacement, | ||
| 555 | true, session_total); | ||
| 556 | return fprintf(fp, "%s\n", bf); | ||
| 533 | } | 557 | } |
| 534 | 558 | ||
| 535 | static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, | 559 | static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, |
| @@ -658,7 +682,7 @@ print_entries: | |||
| 658 | 682 | ||
| 659 | if (h->ms.map == NULL && verbose > 1) { | 683 | if (h->ms.map == NULL && verbose > 1) { |
| 660 | __map_groups__fprintf_maps(&h->thread->mg, | 684 | __map_groups__fprintf_maps(&h->thread->mg, |
| 661 | MAP__FUNCTION, fp); | 685 | MAP__FUNCTION, verbose, fp); |
| 662 | fprintf(fp, "%.10s end\n", graph_dotted_line); | 686 | fprintf(fp, "%.10s end\n", graph_dotted_line); |
| 663 | } | 687 | } |
| 664 | } | 688 | } |
