From f542e7670e48bc9d0aed351c1fd2ae0b65cc6f68 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 5 Jul 2016 08:56:04 +0200 Subject: [PATCH] perf hists: Introduce hist_entry_ops 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 Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1467701765-26194-3-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 31 +++++++++++++++++++++++++++---- tools/perf/util/sort.h | 6 ++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 04f3b52a319c..355b7601ddb7 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -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); } /* diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index ebb59cacd092..7ca37ea17395 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -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 { -- 2.20.1