hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/tools/perf/ui/stdio/hist.c
....@@ -1,15 +1,23 @@
11 // SPDX-License-Identifier: GPL-2.0
22 #include <stdio.h>
3
+#include <stdlib.h>
34 #include <linux/string.h>
45
5
-#include "../../util/util.h"
6
+#include "../../util/callchain.h"
7
+#include "../../util/debug.h"
8
+#include "../../util/event.h"
69 #include "../../util/hist.h"
10
+#include "../../util/map.h"
11
+#include "../../util/maps.h"
12
+#include "../../util/symbol.h"
713 #include "../../util/sort.h"
814 #include "../../util/evsel.h"
915 #include "../../util/srcline.h"
1016 #include "../../util/string2.h"
1117 #include "../../util/thread.h"
12
-#include "../../util/sane_ctype.h"
18
+#include "../../util/block-info.h"
19
+#include <linux/ctype.h>
20
+#include <linux/zalloc.h>
1321
1422 static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
1523 {
....@@ -512,7 +520,7 @@
512520 * dynamic entries are right-aligned but we want left-aligned
513521 * in the hierarchy mode
514522 */
515
- printed += fprintf(fp, "%s%s", sep ?: " ", ltrim(buf));
523
+ printed += fprintf(fp, "%s%s", sep ?: " ", skip_spaces(buf));
516524 }
517525 printed += putc('\n', fp);
518526
....@@ -525,6 +533,49 @@
525533
526534 out:
527535 return printed;
536
+}
537
+
538
+static int hist_entry__block_fprintf(struct hist_entry *he,
539
+ char *bf, size_t size,
540
+ FILE *fp)
541
+{
542
+ struct block_hist *bh = container_of(he, struct block_hist, he);
543
+ int ret = 0;
544
+
545
+ for (unsigned int i = 0; i < bh->block_hists.nr_entries; i++) {
546
+ struct perf_hpp hpp = {
547
+ .buf = bf,
548
+ .size = size,
549
+ .skip = false,
550
+ };
551
+
552
+ bh->block_idx = i;
553
+ hist_entry__snprintf(he, &hpp);
554
+
555
+ if (!hpp.skip)
556
+ ret += fprintf(fp, "%s\n", bf);
557
+ }
558
+
559
+ return ret;
560
+}
561
+
562
+static int hist_entry__individual_block_fprintf(struct hist_entry *he,
563
+ char *bf, size_t size,
564
+ FILE *fp)
565
+{
566
+ int ret = 0;
567
+
568
+ struct perf_hpp hpp = {
569
+ .buf = bf,
570
+ .size = size,
571
+ .skip = false,
572
+ };
573
+
574
+ hist_entry__snprintf(he, &hpp);
575
+ if (!hpp.skip)
576
+ ret += fprintf(fp, "%s\n", bf);
577
+
578
+ return ret;
528579 }
529580
530581 static int hist_entry__fprintf(struct hist_entry *he, size_t size,
....@@ -546,6 +597,12 @@
546597 if (symbol_conf.report_hierarchy)
547598 return hist_entry__hierarchy_fprintf(he, &hpp, hists, fp);
548599
600
+ if (symbol_conf.report_block)
601
+ return hist_entry__block_fprintf(he, bf, size, fp);
602
+
603
+ if (symbol_conf.report_individual_block)
604
+ return hist_entry__individual_block_fprintf(he, bf, size, fp);
605
+
549606 hist_entry__snprintf(he, &hpp);
550607
551608 ret = fprintf(fp, "%s\n", bf);
....@@ -562,10 +619,14 @@
562619 static int print_hierarchy_indent(const char *sep, int indent,
563620 const char *line, FILE *fp)
564621 {
622
+ int width;
623
+
565624 if (sep != NULL || indent < 2)
566625 return 0;
567626
568
- return fprintf(fp, "%-.*s", (indent - 2) * HIERARCHY_INDENT, line);
627
+ width = (indent - 2) * HIERARCHY_INDENT;
628
+
629
+ return fprintf(fp, "%-*.*s", width, width, line);
569630 }
570631
571632 static int hists__fprintf_hierarchy_headers(struct hists *hists,
....@@ -583,7 +644,7 @@
583644 indent = hists->nr_hpp_node;
584645
585646 /* preserve max indent depth for column headers */
586
- print_hierarchy_indent(sep, indent, spaces, fp);
647
+ print_hierarchy_indent(sep, indent, " ", fp);
587648
588649 /* the first hpp_list_node is for overhead columns */
589650 fmt_node = list_first_entry(&hists->hpp_formats,
....@@ -612,7 +673,7 @@
612673
613674 fmt->header(fmt, hpp, hists, 0, NULL);
614675
615
- header_width += fprintf(fp, "%s", trim(hpp->buf));
676
+ header_width += fprintf(fp, "%s", strim(hpp->buf));
616677 }
617678 }
618679
....@@ -788,14 +849,19 @@
788849
789850 indent = hists__overhead_width(hists) + 4;
790851
791
- for (nd = rb_first(&hists->entries); nd; nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD)) {
852
+ for (nd = rb_first_cached(&hists->entries); nd;
853
+ nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD)) {
792854 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
793855 float percent;
794856
795857 if (h->filtered)
796858 continue;
797859
798
- percent = hist_entry__get_percent_limit(h);
860
+ if (symbol_conf.report_individual_block)
861
+ percent = block_info__total_cycles_percent(h);
862
+ else
863
+ percent = hist_entry__get_percent_limit(h);
864
+
799865 if (percent < min_pcnt)
800866 continue;
801867
....@@ -811,7 +877,7 @@
811877 if (!h->leaf && !hist_entry__has_hierarchy_children(h, min_pcnt)) {
812878 int depth = hists->nr_hpp_node + h->depth + 1;
813879
814
- print_hierarchy_indent(sep, depth, spaces, fp);
880
+ print_hierarchy_indent(sep, depth, " ", fp);
815881 fprintf(fp, "%*sno entry >= %.2f%%\n", indent, "", min_pcnt);
816882
817883 if (max_rows && ++nr_rows >= max_rows)
....@@ -819,7 +885,7 @@
819885 }
820886
821887 if (h->ms.map == NULL && verbose > 1) {
822
- map_groups__fprintf(h->thread->mg, fp);
888
+ maps__fprintf(h->thread->maps, fp);
823889 fprintf(fp, "%.10s end\n", graph_dotted_line);
824890 }
825891 }