diff options
-rw-r--r-- | tools/perf/util/hist.c | 60 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 1 |
2 files changed, 61 insertions, 0 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index c1de3b05fe09..7c6e73b1b7ea 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -717,6 +717,42 @@ void hists__inc_nr_events(struct hists *hists, u32 type) | |||
717 | ++hists->stats.nr_events[type]; | 717 | ++hists->stats.nr_events[type]; |
718 | } | 718 | } |
719 | 719 | ||
720 | static struct hist_entry *hists__add_dummy_entry(struct hists *hists, | ||
721 | struct hist_entry *pair) | ||
722 | { | ||
723 | struct rb_node **p = &hists->entries.rb_node; | ||
724 | struct rb_node *parent = NULL; | ||
725 | struct hist_entry *he; | ||
726 | int cmp; | ||
727 | |||
728 | while (*p != NULL) { | ||
729 | parent = *p; | ||
730 | he = rb_entry(parent, struct hist_entry, rb_node); | ||
731 | |||
732 | cmp = hist_entry__cmp(pair, he); | ||
733 | |||
734 | if (!cmp) | ||
735 | goto out; | ||
736 | |||
737 | if (cmp < 0) | ||
738 | p = &(*p)->rb_left; | ||
739 | else | ||
740 | p = &(*p)->rb_right; | ||
741 | } | ||
742 | |||
743 | he = hist_entry__new(pair); | ||
744 | if (he) { | ||
745 | he->stat.nr_events = 0; | ||
746 | he->stat.period = 0; | ||
747 | he->hists = hists; | ||
748 | rb_link_node(&he->rb_node, parent, p); | ||
749 | rb_insert_color(&he->rb_node, &hists->entries); | ||
750 | hists__inc_nr_entries(hists, he); | ||
751 | } | ||
752 | out: | ||
753 | return he; | ||
754 | } | ||
755 | |||
720 | static struct hist_entry *hists__find_entry(struct hists *hists, | 756 | static struct hist_entry *hists__find_entry(struct hists *hists, |
721 | struct hist_entry *he) | 757 | struct hist_entry *he) |
722 | { | 758 | { |
@@ -753,3 +789,27 @@ void hists__match(struct hists *leader, struct hists *other) | |||
753 | hist__entry_add_pair(pos, pair); | 789 | hist__entry_add_pair(pos, pair); |
754 | } | 790 | } |
755 | } | 791 | } |
792 | |||
793 | /* | ||
794 | * Look for entries in the other hists that are not present in the leader, if | ||
795 | * we find them, just add a dummy entry on the leader hists, with period=0, | ||
796 | * nr_events=0, to serve as the list header. | ||
797 | */ | ||
798 | int hists__link(struct hists *leader, struct hists *other) | ||
799 | { | ||
800 | struct rb_node *nd; | ||
801 | struct hist_entry *pos, *pair; | ||
802 | |||
803 | for (nd = rb_first(&other->entries); nd; nd = rb_next(nd)) { | ||
804 | pos = rb_entry(nd, struct hist_entry, rb_node); | ||
805 | |||
806 | if (!hist_entry__has_pairs(pos)) { | ||
807 | pair = hists__add_dummy_entry(leader, pos); | ||
808 | if (pair == NULL) | ||
809 | return -1; | ||
810 | hist__entry_add_pair(pair, pos); | ||
811 | } | ||
812 | } | ||
813 | |||
814 | return 0; | ||
815 | } | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ff1c3963e04f..1278c2c72a96 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -116,6 +116,7 @@ void hists__reset_col_len(struct hists *hists); | |||
116 | void hists__calc_col_len(struct hists *hists, struct hist_entry *he); | 116 | void hists__calc_col_len(struct hists *hists, struct hist_entry *he); |
117 | 117 | ||
118 | void hists__match(struct hists *leader, struct hists *other); | 118 | void hists__match(struct hists *leader, struct hists *other); |
119 | int hists__link(struct hists *leader, struct hists *other); | ||
119 | 120 | ||
120 | struct perf_hpp { | 121 | struct perf_hpp { |
121 | char *buf; | 122 | char *buf; |