perf tools: Remove hists from evsel
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 9 Oct 2014 19:16:00 +0000 (16:16 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 14 Oct 2014 20:32:52 +0000 (17:32 -0300)
Now tools that deals want to have an hists per evsel need to call
hists__init() before creating any evsels, which can be as early as when
parsing the command line, so do it before calling parse_options().

The current tools using hists/hist_entries are report, top and annotate,
change them to request per evsel hists.

This is in preparation for making evsels usable by 3rd party tools, that
not necessarily live in perf's source code repository.

Acked-by: Borislav Petkov <bp@suse.de>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-usjx2la743f10ippj7p1b20x@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-annotate.c
tools/perf/builtin-report.c
tools/perf/builtin-top.c
tools/perf/tests/builtin-test.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/hist.c
tools/perf/util/hist.h

index a5969fa64503529fc0636d99090f1f39f636733e..e7417fe97a9775eae8712d5bb58be2db0d1d7363 100644 (file)
@@ -326,7 +326,10 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
                    "Show event group information together"),
        OPT_END()
        };
-       int ret;
+       int ret = hists__init();
+
+       if (ret < 0)
+               return ret;
 
        argc = parse_options(argc, argv, options, annotate_usage, 0);
 
index 8043b5a7240a19ef8973e5764b2e46a73d4c5934..2cfc4b93991f71008ec336825f207831f6351720 100644 (file)
@@ -568,7 +568,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
        struct stat st;
        bool has_br_stack = false;
        int branch_mode = -1;
-       int ret = -1;
        char callchain_default_opt[] = "fractal,0.5,callee";
        const char * const report_usage[] = {
                "perf report [<options>]",
@@ -695,6 +694,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
        struct perf_data_file file = {
                .mode  = PERF_DATA_MODE_READ,
        };
+       int ret = hists__init();
+
+       if (ret < 0)
+               return ret;
 
        perf_config(report__config, &report);
 
index 8ab9716db5931b3140f71a8714d1b1a24b963f06..0aa7747ff1390e0995a875a6c185697901cb9632 100644 (file)
@@ -1047,7 +1047,6 @@ parse_percent_limit(const struct option *opt, const char *arg,
 
 int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
 {
-       int status = -1;
        char errbuf[BUFSIZ];
        struct perf_top top = {
                .count_filter        = 5,
@@ -1165,6 +1164,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
                "perf top [<options>]",
                NULL
        };
+       int status = hists__init();
+
+       if (status < 0)
+               return status;
 
        top.evlist = perf_evlist__new();
        if (top.evlist == NULL)
index ac655b0700e7648335cc15c45a560c80f35ae27c..162c978f1491a9e49dd6f37e1dd34ccb40d2a540 100644 (file)
@@ -6,6 +6,7 @@
 #include <unistd.h>
 #include <string.h>
 #include "builtin.h"
+#include "hist.h"
 #include "intlist.h"
 #include "tests.h"
 #include "debug.h"
@@ -302,6 +303,10 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
        OPT_END()
        };
        struct intlist *skiplist = NULL;
+        int ret = hists__init();
+
+        if (ret < 0)
+                return ret;
 
        argc = parse_options(argc, argv, test_options, test_usage, 0);
        if (argc >= 1 && !strcmp(argv[0], "list"))
index a0837642744862b792a51165cee7f2fc6320cb1a..7a3c4c47ceda3f0ba3d4414c8d5f7f8d689b9fc2 100644 (file)
@@ -159,16 +159,6 @@ void perf_evsel__calc_id_pos(struct perf_evsel *evsel)
        evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type);
 }
 
-void hists__init(struct hists *hists)
-{
-       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];
-       hists->entries_collapsed = RB_ROOT;
-       hists->entries = RB_ROOT;
-       pthread_mutex_init(&hists->lock, NULL);
-}
-
 void __perf_evsel__set_sample_bit(struct perf_evsel *evsel,
                                  enum perf_event_sample_format bit)
 {
@@ -211,7 +201,6 @@ void perf_evsel__init(struct perf_evsel *evsel,
        evsel->unit        = "";
        evsel->scale       = 1.0;
        INIT_LIST_HEAD(&evsel->node);
-       hists__init(&evsel->hists);
        perf_evsel__object.init(evsel);
        evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
        perf_evsel__calc_id_pos(evsel);
index d6325106c8fd4d8b45dea14d954a506e7a8f19d6..fee927404720a16797b4b1981575ee95f6c17cb5 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/types.h>
 #include "xyarray.h"
 #include "cgroup.h"
-#include "hist.h"
 #include "symbol.h"
 
 struct perf_counts_values {
@@ -66,7 +65,6 @@ struct perf_evsel {
        struct perf_counts      *prev_raw_counts;
        int                     idx;
        u32                     ids;
-       struct hists            hists;
        char                    *name;
        double                  scale;
        const char              *unit;
@@ -100,13 +98,6 @@ union u64_swap {
        u32 val32[2];
 };
 
-#define hists_to_evsel(h) container_of(h, struct perf_evsel, hists)
-
-static inline struct hists *evsel__hists(struct perf_evsel *evsel)
-{
-       return &evsel->hists;
-}
-
 struct cpu_map;
 struct thread_map;
 struct perf_evlist;
@@ -290,8 +281,6 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
        return __perf_evsel__read(evsel, ncpus, nthreads, true);
 }
 
-void hists__init(struct hists *hists);
-
 int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
                             struct perf_sample *sample);
 
index b143e404e5b135e90b841a1a2414bb383476ebe8..6e88b9e395df67abb0458eea80878112acab0b0a 100644 (file)
@@ -1447,3 +1447,31 @@ int perf_hist_config(const char *var, const char *value)
 
        return 0;
 }
+
+static int hists_evsel__init(struct perf_evsel *evsel)
+{
+       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];
+       hists->entries_collapsed = RB_ROOT;
+       hists->entries = RB_ROOT;
+       pthread_mutex_init(&hists->lock, NULL);
+       return 0;
+}
+
+/*
+ * XXX We probably need a hists_evsel__exit() to free the hist_entries
+ * stored in the rbtree...
+ */
+
+int hists__init(void)
+{
+       int err = perf_evsel__object_config(sizeof(struct hists_evsel),
+                                           hists_evsel__init, NULL);
+       if (err)
+               fputs("FATAL ERROR: Couldn't setup hists class\n", stderr);
+
+       return err;
+}
index ebfc25886cac56546e49461438f1a31c8e74dbb8..d0ef9a19a7445caaf7bdc1d21b42ea2d1087a2a9 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/types.h>
 #include <pthread.h>
 #include "callchain.h"
+#include "evsel.h"
 #include "header.h"
 #include "color.h"
 #include "ui/progress.h"
@@ -158,6 +159,25 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
 void hists__match(struct hists *leader, struct hists *other);
 int hists__link(struct hists *leader, struct hists *other);
 
+struct hists_evsel {
+       struct perf_evsel evsel;
+       struct hists      hists;
+};
+
+static inline struct perf_evsel *hists_to_evsel(struct hists *hists)
+{
+       struct hists_evsel *hevsel = container_of(hists, struct hists_evsel, hists);
+       return &hevsel->evsel;
+}
+
+static inline struct hists *evsel__hists(struct perf_evsel *evsel)
+{
+       struct hists_evsel *hevsel = (struct hists_evsel *)evsel;
+       return &hevsel->hists;
+}
+
+int hists__init(void);
+
 struct perf_hpp {
        char *buf;
        size_t size;