perf hists: Export a couple of hist functions
[deliverable/linux.git] / tools / perf / util / hist.c
index 56e97f5af5984f20a3af0157874a1e91aae6ffb9..c226303e3da045743fe676c7c2ffc0ff13eac674 100644 (file)
@@ -254,6 +254,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
        he_stat__decay(&he->stat);
        if (symbol_conf.cumulate_callchain)
                he_stat__decay(he->stat_acc);
+       decay_callchain(he->callchain);
 
        diff = prev_period - he->stat.period;
 
@@ -369,6 +370,25 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template,
                if (symbol_conf.use_callchain)
                        callchain_init(he->callchain);
 
+               if (he->raw_data) {
+                       he->raw_data = memdup(he->raw_data, he->raw_size);
+
+                       if (he->raw_data == NULL) {
+                               map__put(he->ms.map);
+                               if (he->branch_info) {
+                                       map__put(he->branch_info->from.map);
+                                       map__put(he->branch_info->to.map);
+                                       free(he->branch_info);
+                               }
+                               if (he->mem_info) {
+                                       map__put(he->mem_info->iaddr.map);
+                                       map__put(he->mem_info->daddr.map);
+                               }
+                               free(he->stat_acc);
+                               free(he);
+                               return NULL;
+                       }
+               }
                INIT_LIST_HEAD(&he->pairs.node);
                thread__get(he->thread);
        }
@@ -461,7 +481,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
                                      struct symbol *sym_parent,
                                      struct branch_info *bi,
                                      struct mem_info *mi,
-                                     u64 period, u64 weight, u64 transaction,
+                                     struct perf_sample *sample,
                                      bool sample_self)
 {
        struct hist_entry entry = {
@@ -478,15 +498,17 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
                .level   = al->level,
                .stat = {
                        .nr_events = 1,
-                       .period = period,
-                       .weight = weight,
+                       .period = sample->period,
+                       .weight = sample->weight,
                },
                .parent = sym_parent,
                .filtered = symbol__parent_filter(sym_parent) | al->filtered,
                .hists  = hists,
                .branch_info = bi,
                .mem_info = mi,
-               .transaction = transaction,
+               .transaction = sample->transaction,
+               .raw_data = sample->raw_data,
+               .raw_size = sample->raw_size,
        };
 
        return hists__findnew_entry(hists, &entry, al, sample_self);
@@ -526,12 +548,13 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
        u64 cost;
        struct mem_info *mi = iter->priv;
        struct hists *hists = evsel__hists(iter->evsel);
+       struct perf_sample *sample = iter->sample;
        struct hist_entry *he;
 
        if (mi == NULL)
                return -EINVAL;
 
-       cost = iter->sample->weight;
+       cost = sample->weight;
        if (!cost)
                cost = 1;
 
@@ -542,8 +565,10 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
         * and this is indirectly achieved by passing period=weight here
         * and the he_stat__add_period() function.
         */
+       sample->period = cost;
+
        he = __hists__add_entry(hists, al, iter->parent, NULL, mi,
-                               cost, cost, 0, true);
+                               sample, true);
        if (!he)
                return -ENOMEM;
 
@@ -630,6 +655,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
        struct branch_info *bi;
        struct perf_evsel *evsel = iter->evsel;
        struct hists *hists = evsel__hists(evsel);
+       struct perf_sample *sample = iter->sample;
        struct hist_entry *he = NULL;
        int i = iter->curr;
        int err = 0;
@@ -643,9 +669,11 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
         * The report shows the percentage of total branches captured
         * and not events sampled. Thus we use a pseudo period of 1.
         */
+       sample->period = 1;
+       sample->weight = bi->flags.cycles ? bi->flags.cycles : 1;
+
        he = __hists__add_entry(hists, al, iter->parent, &bi[i], NULL,
-                               1, bi->flags.cycles ? bi->flags.cycles : 1,
-                               0, true);
+                               sample, true);
        if (he == NULL)
                return -ENOMEM;
 
@@ -682,8 +710,7 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location
        struct hist_entry *he;
 
        he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
-                               sample->period, sample->weight,
-                               sample->transaction, true);
+                               sample, true);
        if (he == NULL)
                return -ENOMEM;
 
@@ -744,8 +771,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
        int err = 0;
 
        he = __hists__add_entry(hists, al, iter->parent, NULL, NULL,
-                               sample->period, sample->weight,
-                               sample->transaction, true);
+                               sample, true);
        if (he == NULL)
                return -ENOMEM;
 
@@ -797,6 +823,8 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
                        .sym = al->sym,
                },
                .parent = iter->parent,
+               .raw_data = sample->raw_data,
+               .raw_size = sample->raw_size,
        };
        int i;
        struct callchain_cursor cursor;
@@ -818,8 +846,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
        }
 
        he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
-                               sample->period, sample->weight,
-                               sample->transaction, false);
+                               sample, false);
        if (he == NULL)
                return -ENOMEM;
 
@@ -971,6 +998,8 @@ void hist_entry__delete(struct hist_entry *he)
        if (he->srcfile && he->srcfile[0])
                free(he->srcfile);
        free_callchain(he->callchain);
+       free(he->trace_output);
+       free(he->raw_data);
        free(he);
 }
 
@@ -978,9 +1007,8 @@ void hist_entry__delete(struct hist_entry *he)
  * collapse the histogram
  */
 
-static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
-                                        struct rb_root *root,
-                                        struct hist_entry *he)
+bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
+                                 struct rb_root *root, struct hist_entry *he)
 {
        struct rb_node **p = &root->rb_node;
        struct rb_node *parent = NULL;
@@ -1020,7 +1048,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
        return true;
 }
 
-static struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
+struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
 {
        struct rb_root *root;
 
@@ -1084,7 +1112,7 @@ static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b)
        int64_t cmp = 0;
 
        perf_hpp__for_each_sort_list(fmt) {
-               if (perf_hpp__should_skip(fmt))
+               if (perf_hpp__should_skip(fmt, a->hists))
                        continue;
 
                cmp = fmt->sort(fmt, a, b);
@@ -1555,10 +1583,8 @@ int perf_hist_config(const char *var, const char *value)
        return 0;
 }
 
-static int hists_evsel__init(struct perf_evsel *evsel)
+int __hists__init(struct hists *hists)
 {
-       struct hists *hists = evsel__hists(evsel);
-
        memset(hists, 0, sizeof(*hists));
        hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
        hists->entries_in = &hists->entries_in_array[0];
@@ -1598,6 +1624,14 @@ static void hists_evsel__exit(struct perf_evsel *evsel)
        hists__delete_all_entries(hists);
 }
 
+static int hists_evsel__init(struct perf_evsel *evsel)
+{
+       struct hists *hists = evsel__hists(evsel);
+
+       __hists__init(hists);
+       return 0;
+}
+
 /*
  * XXX We probably need a hists_evsel__exit() to free the hist_entries
  * stored in the rbtree...
This page took 0.027388 seconds and 5 git commands to generate.