summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r--tools/perf/builtin-diff.c92
1 files changed, 36 insertions, 56 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index b2e7d39f099b..4af0b580b046 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -275,43 +275,6 @@ static struct perf_tool tool = {
.ordering_requires_timestamps = true,
};
-static void insert_hist_entry_by_name(struct rb_root *root,
- struct hist_entry *he)
-{
- struct rb_node **p = &root->rb_node;
- struct rb_node *parent = NULL;
- struct hist_entry *iter;
-
- while (*p != NULL) {
- parent = *p;
- iter = rb_entry(parent, struct hist_entry, rb_node);
- if (hist_entry__cmp(he, iter) < 0)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
- }
-
- rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, root);
-}
-
-static void hists__name_resort(struct hists *self)
-{
- struct rb_root tmp = RB_ROOT;
- struct rb_node *next = rb_first(&self->entries);
-
- while (next != NULL) {
- struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node);
-
- next = rb_next(&n->rb_node);
-
- rb_erase(&n->rb_node, &self->entries);
- insert_hist_entry_by_name(&tmp, n);
- }
-
- self->entries = tmp;
-}
-
static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
struct perf_evlist *evlist)
{
@@ -324,30 +287,34 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
return NULL;
}
-static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name)
+static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
{
struct perf_evsel *evsel;
list_for_each_entry(evsel, &evlist->entries, node) {
struct hists *hists = &evsel->hists;
- hists__output_resort(hists);
-
- if (name)
- hists__name_resort(hists);
+ hists__collapse_resort(hists);
}
}
static void hists__baseline_only(struct hists *hists)
{
- struct rb_node *next = rb_first(&hists->entries);
+ struct rb_root *root;
+ struct rb_node *next;
+
+ if (sort__need_collapse)
+ root = &hists->entries_collapsed;
+ else
+ root = hists->entries_in;
+ next = rb_first(root);
while (next != NULL) {
- struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node);
+ struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
- next = rb_next(&he->rb_node);
+ next = rb_next(&he->rb_node_in);
if (!hist_entry__next_pair(he)) {
- rb_erase(&he->rb_node, &hists->entries);
+ rb_erase(&he->rb_node_in, root);
hist_entry__free(he);
}
}
@@ -447,19 +414,30 @@ static void insert_hist_entry_by_compute(struct rb_root *root,
static void hists__compute_resort(struct hists *hists)
{
- struct rb_root tmp = RB_ROOT;
- struct rb_node *next = rb_first(&hists->entries);
+ struct rb_root *root;
+ struct rb_node *next;
+
+ if (sort__need_collapse)
+ root = &hists->entries_collapsed;
+ else
+ root = hists->entries_in;
+
+ hists->entries = RB_ROOT;
+ next = rb_first(root);
+
+ hists->nr_entries = 0;
+ hists->stats.total_period = 0;
+ hists__reset_col_len(hists);
while (next != NULL) {
- struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node);
+ struct hist_entry *he;
- next = rb_next(&he->rb_node);
+ he = rb_entry(next, struct hist_entry, rb_node_in);
+ next = rb_next(&he->rb_node_in);
- rb_erase(&he->rb_node, &hists->entries);
- insert_hist_entry_by_compute(&tmp, he, compute);
+ insert_hist_entry_by_compute(&hists->entries, he, compute);
+ hists__inc_nr_entries(hists, he);
}
-
- hists->entries = tmp;
}
static void hists__process(struct hists *old, struct hists *new)
@@ -474,6 +452,8 @@ static void hists__process(struct hists *old, struct hists *new)
if (sort_compute) {
hists__precompute(new);
hists__compute_resort(new);
+ } else {
+ hists__output_resort(new);
}
hists__fprintf(new, true, 0, 0, stdout);
@@ -505,8 +485,8 @@ static int __cmd_diff(void)
evlist_old = older->evlist;
evlist_new = newer->evlist;
- perf_evlist__resort_hists(evlist_old, true);
- perf_evlist__resort_hists(evlist_new, false);
+ perf_evlist__collapse_resort(evlist_old);
+ perf_evlist__collapse_resort(evlist_new);
list_for_each_entry(evsel, &evlist_new->entries, node) {
struct perf_evsel *evsel_old;