perf session: Change perf_session post processing functions to take histogram tree
[pandora-kernel.git] / tools / perf / builtin-report.c
index 860f1ee..294b4cf 100644 (file)
@@ -34,6 +34,8 @@
 static char            const *input_name = "perf.data";
 
 static int             force;
+static bool            hide_unresolved;
+static bool            dont_use_callchains;
 
 static int             show_threads;
 static struct perf_read_values show_threads_values;
@@ -54,7 +56,8 @@ static int perf_session__add_hist_entry(struct perf_session *self,
        if ((sort__has_parent || symbol_conf.use_callchain) && chain)
                syms = perf_session__resolve_callchain(self, al->thread,
                                                       chain, &parent);
-       he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
+       he = __perf_session__add_hist_entry(&self->hists, al, parent,
+                                           count, &hit);
        if (he == NULL)
                return -ENOMEM;
 
@@ -91,11 +94,8 @@ static int process_sample_event(event_t *event, struct perf_session *session)
 
        event__parse_sample(event, session->sample_type, &data);
 
-       dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
-               event->header.misc,
-               data.pid, data.tid,
-               (void *)(long)data.ip,
-               (long long)data.period);
+       dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
+                   data.pid, data.tid, data.ip, data.period);
 
        if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
                unsigned int i;
@@ -121,7 +121,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
                return -1;
        }
 
-       if (al.filtered)
+       if (al.filtered || (hide_unresolved && al.sym == NULL))
                return 0;
 
        if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
@@ -156,14 +156,14 @@ static int process_read_event(event_t *event, struct perf_session *session __use
        return 0;
 }
 
-static int sample_type_check(struct perf_session *session)
+static int perf_session__setup_sample_type(struct perf_session *self)
 {
-       if (!(session->sample_type & PERF_SAMPLE_CALLCHAIN)) {
+       if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) {
                if (sort__has_parent) {
                        fprintf(stderr, "selected --sort parent, but no"
                                        " callchain data. Did you call"
                                        " perf record without -g?\n");
-                       return -1;
+                       return -EINVAL;
                }
                if (symbol_conf.use_callchain) {
                        fprintf(stderr, "selected -g but no callchain data."
@@ -171,12 +171,13 @@ static int sample_type_check(struct perf_session *session)
                                        " -g?\n");
                        return -1;
                }
-       } else if (callchain_param.mode != CHAIN_NONE && !symbol_conf.use_callchain) {
+       } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE &&
+                  !symbol_conf.use_callchain) {
                        symbol_conf.use_callchain = true;
                        if (register_callchain_param(&callchain_param) < 0) {
                                fprintf(stderr, "Can't register callchain"
                                                " params\n");
-                               return -1;
+                               return -EINVAL;
                        }
        }
 
@@ -184,20 +185,18 @@ static int sample_type_check(struct perf_session *session)
 }
 
 static struct perf_event_ops event_ops = {
-       .process_sample_event   = process_sample_event,
-       .process_mmap_event     = event__process_mmap,
-       .process_comm_event     = event__process_comm,
-       .process_exit_event     = event__process_task,
-       .process_fork_event     = event__process_task,
-       .process_lost_event     = event__process_lost,
-       .process_read_event     = process_read_event,
-       .sample_type_check      = sample_type_check,
+       .sample = process_sample_event,
+       .mmap   = event__process_mmap,
+       .comm   = event__process_comm,
+       .exit   = event__process_task,
+       .fork   = event__process_task,
+       .lost   = event__process_lost,
+       .read   = process_read_event,
 };
 
-
 static int __cmd_report(void)
 {
-       int ret;
+       int ret = -EINVAL;
        struct perf_session *session;
 
        session = perf_session__new(input_name, O_RDONLY, force);
@@ -207,6 +206,10 @@ static int __cmd_report(void)
        if (show_threads)
                perf_read_values_init(&show_threads_values);
 
+       ret = perf_session__setup_sample_type(session);
+       if (ret)
+               goto out_delete;
+
        ret = perf_session__process_events(session, &event_ops);
        if (ret)
                goto out_delete;
@@ -222,10 +225,12 @@ static int __cmd_report(void)
        if (verbose > 2)
                dsos__fprintf(stdout);
 
-       perf_session__collapse_resort(session);
-       perf_session__output_resort(session, session->events_stats.total);
+       perf_session__collapse_resort(&session->hists);
+       perf_session__output_resort(&session->hists,
+                                   session->events_stats.total);
        fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total);
-       perf_session__fprintf_hists(session, NULL, false, stdout);
+       perf_session__fprintf_hists(&session->hists, NULL, false, stdout,
+                                   session->events_stats.total);
        if (sort_order == default_sort_order &&
            parent_pattern == default_parent_pattern)
                fprintf(stdout, "#\n# (For a higher level overview, try: perf report --sort comm,dso)\n#\n");
@@ -243,11 +248,19 @@ out_delete:
 
 static int
 parse_callchain_opt(const struct option *opt __used, const char *arg,
-                   int unset __used)
+                   int unset)
 {
        char *tok;
        char *endptr;
 
+       /*
+        * --no-call-graph
+        */
+       if (unset) {
+               dont_use_callchains = true;
+               return 0;
+       }
+
        symbol_conf.use_callchain = true;
 
        if (!arg)
@@ -319,7 +332,7 @@ static const struct option options[] = {
                   "pretty printing style key: normal raw"),
        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
                   "sort by key(s): pid, comm, dso, symbol, parent"),
-       OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths,
+       OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths,
                    "Don't shorten the pathnames taking into account the cwd"),
        OPT_STRING('p', "parent", &parent_pattern, "regex",
                   "regex filter to identify parent, see: '--sort parent'"),
@@ -340,6 +353,8 @@ static const struct option options[] = {
        OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
                   "separator for columns, no spaces will be added between "
                   "columns '.' is reserved."),
+       OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved,
+                   "Only display entries resolved to a symbol"),
        OPT_END()
 };