From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759880AbcBYHne (ORCPT ); Thu, 25 Feb 2016 02:43:34 -0500 Received: from torg.zytor.com ([198.137.202.12]:57466 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1759241AbcBYHna (ORCPT ); Thu, 25 Feb 2016 02:43:30 -0500 Date: Wed, 24 Feb 2016 23:41:46 -0800 From: tip-bot for Namhyung Kim Message-ID: Cc: dsahern@gmail.com, namhyung@kernel.org, acme@redhat.com, jolsa@kernel.org, mingo@kernel.org, penberg@kernel.org, andi@firstfloor.org, eranian@google.com, tglx@linutronix.de, linux-kernel@vger.kernel.org, peterz@infradead.org, wangnan0@huawei.com, hpa@zytor.com Reply-To: eranian@google.com, tglx@linutronix.de, linux-kernel@vger.kernel.org, peterz@infradead.org, wangnan0@huawei.com, hpa@zytor.com, dsahern@gmail.com, namhyung@kernel.org, acme@redhat.com, mingo@kernel.org, jolsa@kernel.org, penberg@kernel.org, andi@firstfloor.org In-Reply-To: <1456326830-30456-5-git-send-email-namhyung@kernel.org> References: <1456326830-30456-5-git-send-email-namhyung@kernel.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] perf hists: Add helper functions for hierarchy mode Git-Commit-ID: 8c01872fe3c17fde1ce74eecf523d6d7fce5ffec X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 8c01872fe3c17fde1ce74eecf523d6d7fce5ffec Gitweb: http://git.kernel.org/tip/8c01872fe3c17fde1ce74eecf523d6d7fce5ffec Author: Namhyung Kim AuthorDate: Thu, 25 Feb 2016 00:13:36 +0900 Committer: Arnaldo Carvalho de Melo CommitDate: Wed, 24 Feb 2016 16:55:17 -0300 perf hists: Add helper functions for hierarchy mode The rb_hierarchy_{next,prev,last} functions are to traverse all hist entries in a hierarchy. They will be used by various function which supports hierarchy output. As the rb_hierarchy_next() is used to traverse the whole hierarchy, it sometime needs to visit entries regardless of current folding state. So add enum hierarchy_move_dir and pass it to __rb_hierarchy_next() for those cases. Signed-off-by: Namhyung Kim Acked-by: Pekka Enberg Cc: Andi Kleen Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Wang Nan Link: http://lkml.kernel.org/r/1456326830-30456-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/hist.h | 16 +++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6ddac2f..358af7e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1500,6 +1500,62 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog) output_resort(hists, prog, symbol_conf.use_callchain); } +static bool can_goto_child(struct hist_entry *he, enum hierarchy_move_dir hmd) +{ + if (he->leaf || hmd == HMD_FORCE_SIBLING) + return false; + + if (he->unfolded || hmd == HMD_FORCE_CHILD) + return true; + + return false; +} + +struct rb_node *rb_hierarchy_last(struct rb_node *node) +{ + struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node); + + while (can_goto_child(he, HMD_NORMAL)) { + node = rb_last(&he->hroot_out); + he = rb_entry(node, struct hist_entry, rb_node); + } + return node; +} + +struct rb_node *__rb_hierarchy_next(struct rb_node *node, enum hierarchy_move_dir hmd) +{ + struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node); + + if (can_goto_child(he, hmd)) + node = rb_first(&he->hroot_out); + else + node = rb_next(node); + + while (node == NULL) { + he = he->parent_he; + if (he == NULL) + break; + + node = rb_next(&he->rb_node); + } + return node; +} + +struct rb_node *rb_hierarchy_prev(struct rb_node *node) +{ + struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node); + + node = rb_prev(node); + if (node) + return rb_hierarchy_last(node); + + he = he->parent_he; + if (he == NULL) + return NULL; + + return &he->rb_node; +} + static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h, enum hist_filter filter) { diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 044419b3..5690906 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -418,4 +418,20 @@ int perf_hist_config(const char *var, const char *value); void perf_hpp_list__init(struct perf_hpp_list *list); +enum hierarchy_move_dir { + HMD_NORMAL, + HMD_FORCE_SIBLING, + HMD_FORCE_CHILD, +}; + +struct rb_node *rb_hierarchy_last(struct rb_node *node); +struct rb_node *__rb_hierarchy_next(struct rb_node *node, + enum hierarchy_move_dir hmd); +struct rb_node *rb_hierarchy_prev(struct rb_node *node); + +static inline struct rb_node *rb_hierarchy_next(struct rb_node *node) +{ + return __rb_hierarchy_next(node, HMD_NORMAL); +} + #endif /* __PERF_HIST_H */