aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/hist.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r--tools/perf/util/hist.c66
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
188void perf_session__output_resort(struct rb_root *hists, u64 total_samples) 189u64 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
213static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) 217static 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
455size_t hist_entry__fprintf(struct hist_entry *self, 459int 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
546int 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
535static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, 559static 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 }