perf hists: Introduce hist_entry_ops
authorJiri Olsa <jolsa@kernel.org>
Tue, 5 Jul 2016 06:56:04 +0000 (08:56 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 12 Jul 2016 03:00:39 +0000 (00:00 -0300)
Introducing allocation callbacks, that allows to extend current
hist_entry object into objects with special needs without polluting the
current hist_entry object.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1467701765-26194-3-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/hist.c
tools/perf/util/sort.h

index 04f3b52a319c6d655adc89e590e5573ddc2ecc15..355b7601ddb7cb68c8de4867afc16bbf38c0a2bd 100644 (file)
@@ -424,21 +424,42 @@ static int hist_entry__init(struct hist_entry *he,
        return 0;
 }
 
+static void *hist_entry__zalloc(size_t size)
+{
+       return zalloc(size + sizeof(struct hist_entry));
+}
+
+static void hist_entry__free(void *ptr)
+{
+       free(ptr);
+}
+
+static struct hist_entry_ops default_ops = {
+       .new    = hist_entry__zalloc,
+       .free   = hist_entry__free,
+};
+
 static struct hist_entry *hist_entry__new(struct hist_entry *template,
                                          bool sample_self)
 {
+       struct hist_entry_ops *ops = template->ops;
        size_t callchain_size = 0;
        struct hist_entry *he;
        int err = 0;
 
+       if (!ops)
+               ops = template->ops = &default_ops;
+
        if (symbol_conf.use_callchain)
                callchain_size = sizeof(struct callchain_root);
 
-       he = zalloc(sizeof(*he) + callchain_size);
+       he = ops->new(callchain_size);
        if (he) {
                err = hist_entry__init(he, template, sample_self);
-               if (err)
-                       zfree(&he);
+               if (err) {
+                       ops->free(he);
+                       he = NULL;
+               }
        }
 
        return he;
@@ -1050,6 +1071,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 
 void hist_entry__delete(struct hist_entry *he)
 {
+       struct hist_entry_ops *ops = he->ops;
+
        thread__zput(he->thread);
        map__zput(he->ms.map);
 
@@ -1074,7 +1097,7 @@ void hist_entry__delete(struct hist_entry *he)
        free_callchain(he->callchain);
        free(he->trace_output);
        free(he->raw_data);
-       free(he);
+       ops->free(he);
 }
 
 /*
index ebb59cacd092fa919e45a447a6e3e3ad70a0c880..7ca37ea1739559e1e3f064c9260d5d078cb5b84f 100644 (file)
@@ -67,6 +67,11 @@ struct hist_entry_diff {
        };
 };
 
+struct hist_entry_ops {
+       void    *(*new)(size_t size);
+       void    (*free)(void *ptr);
+};
+
 /**
  * struct hist_entry - histogram entry
  *
@@ -125,6 +130,7 @@ struct hist_entry {
        void                    *trace_output;
        struct perf_hpp_list    *hpp_list;
        struct hist_entry       *parent_he;
+       struct hist_entry_ops   *ops;
        union {
                /* this is for hierarchical entry structure */
                struct {