diff options
Diffstat (limited to 'tools/perf/ui/stdio/hist.c')
-rw-r--r-- | tools/perf/ui/stdio/hist.c | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index ae7a75432249..194e2f42ff5d 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -308,10 +308,51 @@ static size_t hist_entry__callchain_fprintf(struct hist_entry *he, | |||
308 | return hist_entry_callchain__fprintf(he, total_period, left_margin, fp); | 308 | return hist_entry_callchain__fprintf(he, total_period, left_margin, fp); |
309 | } | 309 | } |
310 | 310 | ||
311 | static inline void advance_hpp(struct perf_hpp *hpp, int inc) | ||
312 | { | ||
313 | hpp->buf += inc; | ||
314 | hpp->size -= inc; | ||
315 | } | ||
316 | |||
317 | static int hist_entry__period_snprintf(struct perf_hpp *hpp, | ||
318 | struct hist_entry *he, | ||
319 | bool color) | ||
320 | { | ||
321 | const char *sep = symbol_conf.field_sep; | ||
322 | struct perf_hpp_fmt *fmt; | ||
323 | char *start = hpp->buf; | ||
324 | int ret; | ||
325 | bool first = true; | ||
326 | |||
327 | if (symbol_conf.exclude_other && !he->parent) | ||
328 | return 0; | ||
329 | |||
330 | perf_hpp__for_each_format(fmt) { | ||
331 | /* | ||
332 | * If there's no field_sep, we still need | ||
333 | * to display initial ' '. | ||
334 | */ | ||
335 | if (!sep || !first) { | ||
336 | ret = scnprintf(hpp->buf, hpp->size, "%s", sep ?: " "); | ||
337 | advance_hpp(hpp, ret); | ||
338 | } else | ||
339 | first = false; | ||
340 | |||
341 | if (color && fmt->color) | ||
342 | ret = fmt->color(fmt, hpp, he); | ||
343 | else | ||
344 | ret = fmt->entry(fmt, hpp, he); | ||
345 | |||
346 | advance_hpp(hpp, ret); | ||
347 | } | ||
348 | |||
349 | return hpp->buf - start; | ||
350 | } | ||
351 | |||
311 | static int hist_entry__fprintf(struct hist_entry *he, size_t size, | 352 | static int hist_entry__fprintf(struct hist_entry *he, size_t size, |
312 | struct hists *hists, FILE *fp) | 353 | struct hists *hists, |
354 | char *bf, size_t bfsz, FILE *fp) | ||
313 | { | 355 | { |
314 | char bf[512]; | ||
315 | int ret; | 356 | int ret; |
316 | struct perf_hpp hpp = { | 357 | struct perf_hpp hpp = { |
317 | .buf = bf, | 358 | .buf = bf, |
@@ -319,8 +360,8 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, | |||
319 | }; | 360 | }; |
320 | bool color = !symbol_conf.field_sep; | 361 | bool color = !symbol_conf.field_sep; |
321 | 362 | ||
322 | if (size == 0 || size > sizeof(bf)) | 363 | if (size == 0 || size > bfsz) |
323 | size = hpp.size = sizeof(bf); | 364 | size = hpp.size = bfsz; |
324 | 365 | ||
325 | ret = hist_entry__period_snprintf(&hpp, he, color); | 366 | ret = hist_entry__period_snprintf(&hpp, he, color); |
326 | hist_entry__sort_snprintf(he, bf + ret, size - ret, hists); | 367 | hist_entry__sort_snprintf(he, bf + ret, size - ret, hists); |
@@ -351,6 +392,8 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
351 | .ptr = hists_to_evsel(hists), | 392 | .ptr = hists_to_evsel(hists), |
352 | }; | 393 | }; |
353 | bool first = true; | 394 | bool first = true; |
395 | size_t linesz; | ||
396 | char *line = NULL; | ||
354 | 397 | ||
355 | init_rem_hits(); | 398 | init_rem_hits(); |
356 | 399 | ||
@@ -365,7 +408,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
365 | else | 408 | else |
366 | first = false; | 409 | first = false; |
367 | 410 | ||
368 | fmt->header(&dummy_hpp); | 411 | fmt->header(fmt, &dummy_hpp); |
369 | fprintf(fp, "%s", bf); | 412 | fprintf(fp, "%s", bf); |
370 | } | 413 | } |
371 | 414 | ||
@@ -410,7 +453,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
410 | else | 453 | else |
411 | first = false; | 454 | first = false; |
412 | 455 | ||
413 | width = fmt->width(&dummy_hpp); | 456 | width = fmt->width(fmt, &dummy_hpp); |
414 | for (i = 0; i < width; i++) | 457 | for (i = 0; i < width; i++) |
415 | fprintf(fp, "."); | 458 | fprintf(fp, "."); |
416 | } | 459 | } |
@@ -438,6 +481,13 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
438 | goto out; | 481 | goto out; |
439 | 482 | ||
440 | print_entries: | 483 | print_entries: |
484 | linesz = hists__sort_list_width(hists) + 3 + 1; | ||
485 | line = malloc(linesz); | ||
486 | if (line == NULL) { | ||
487 | ret = -1; | ||
488 | goto out; | ||
489 | } | ||
490 | |||
441 | for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { | 491 | for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { |
442 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 492 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
443 | float percent = h->stat.period * 100.0 / | 493 | float percent = h->stat.period * 100.0 / |
@@ -449,10 +499,10 @@ print_entries: | |||
449 | if (percent < min_pcnt) | 499 | if (percent < min_pcnt) |
450 | continue; | 500 | continue; |
451 | 501 | ||
452 | ret += hist_entry__fprintf(h, max_cols, hists, fp); | 502 | ret += hist_entry__fprintf(h, max_cols, hists, line, linesz, fp); |
453 | 503 | ||
454 | if (max_rows && ++nr_rows >= max_rows) | 504 | if (max_rows && ++nr_rows >= max_rows) |
455 | goto out; | 505 | break; |
456 | 506 | ||
457 | if (h->ms.map == NULL && verbose > 1) { | 507 | if (h->ms.map == NULL && verbose > 1) { |
458 | __map_groups__fprintf_maps(&h->thread->mg, | 508 | __map_groups__fprintf_maps(&h->thread->mg, |
@@ -460,6 +510,8 @@ print_entries: | |||
460 | fprintf(fp, "%.10s end\n", graph_dotted_line); | 510 | fprintf(fp, "%.10s end\n", graph_dotted_line); |
461 | } | 511 | } |
462 | } | 512 | } |
513 | |||
514 | free(line); | ||
463 | out: | 515 | out: |
464 | free(rem_sq_bracket); | 516 | free(rem_sq_bracket); |
465 | 517 | ||