cregit-Linux how code gets into the kernel

Release 4.10 tools/perf/ui/browsers/hists.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/rbtree.h>

#include "../../util/evsel.h"
#include "../../util/evlist.h"
#include "../../util/hist.h"
#include "../../util/pstack.h"
#include "../../util/sort.h"
#include "../../util/util.h"
#include "../../util/top.h"
#include "../../arch/common.h"

#include "../browsers/hists.h"
#include "../helpline.h"
#include "../util.h"
#include "../ui.h"
#include "map.h"
#include "annotate.h"

extern void hist_browser__init_hpp(void);

static int perf_evsel_browser_title(struct hist_browser *browser,
				    char *bf, size_t size);
static void hist_browser__update_nr_entries(struct hist_browser *hb);

static struct rb_node *hists__filter_entries(struct rb_node *nd,
					     float min_pcnt);


static bool hist_browser__has_filter(struct hist_browser *hb) { return hists__has_filter(hb->hists) || hb->min_pcnt || symbol_conf.has_filter || hb->c2c_filter; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim2374.19%133.33%
arnaldo carvalho de meloarnaldo carvalho de melo412.90%133.33%
jiri olsajiri olsa412.90%133.33%
Total31100.00%3100.00%


static int hist_browser__get_folding(struct hist_browser *browser) { struct rb_node *nd; struct hists *hists = browser->hists; int unfolded_rows = 0; for (nd = rb_first(&hists->entries); (nd = hists__filter_entries(nd, browser->min_pcnt)) != NULL; nd = rb_hierarchy_next(nd)) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); if (he->leaf && he->unfolded) unfolded_rows += he->nr_rows; } return unfolded_rows; }

Contributors

PersonTokensPropCommitsCommitProp
he kuanghe kuang9595.00%150.00%
namhyung kimnamhyung kim55.00%150.00%
Total100100.00%2100.00%


static u32 hist_browser__nr_entries(struct hist_browser *hb) { u32 nr_entries; if (symbol_conf.report_hierarchy) nr_entries = hb->nr_hierarchy_entries; else if (hist_browser__has_filter(hb)) nr_entries = hb->nr_non_filtered_entries; else nr_entries = hb->hists->nr_entries; hb->nr_callchain_rows = hist_browser__get_folding(hb); return nr_entries + hb->nr_callchain_rows; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim5686.15%266.67%
he kuanghe kuang913.85%133.33%
Total65100.00%3100.00%


static void hist_browser__update_rows(struct hist_browser *hb) { struct ui_browser *browser = &hb->b; struct hists *hists = hb->hists; struct perf_hpp_list *hpp_list = hists->hpp_list; u16 header_offset, index_row; header_offset = hb->show_headers ? hpp_list->nr_header_lines : 0; browser->rows = browser->height - header_offset; /* * Verify if we were at the last line and that line isn't * visibe because we now show the header line(s). */ index_row = browser->index - browser->top_idx; if (index_row >= browser->rows) browser->index -= index_row - browser->rows + 1; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de melo* (jori olsa*?)arnaldo carvalho de melo* (jori olsa*?)7072.16%150.00%
jiri olsajiri olsa2727.84%150.00%
Total97100.00%2100.00%


static void hist_browser__refresh_dimensions(struct ui_browser *browser) { struct hist_browser *hb = container_of(browser, struct hist_browser, b); /* 3 == +/- toggle symbol before actual hist_entry rendering */ browser->width = 3 + (hists__sort_list_width(hb->hists) + sizeof("[k]")); /* * FIXME: Just keeping existing behaviour, but this really should be * before updating browser->width, as it will invalidate the * calculation above. Fix this and the fallout in another * changeset. */ ui_browser__refresh_dimensions(browser); hist_browser__update_rows(hb); }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo5391.38%375.00%
arnaldo carvalho de melo* (jori olsa*?)arnaldo carvalho de melo* (jori olsa*?)58.62%125.00%
Total58100.00%4100.00%


static void hist_browser__gotorc(struct hist_browser *browser, int row, int column) { struct hists *hists = browser->hists; struct perf_hpp_list *hpp_list = hists->hpp_list; u16 header_offset; header_offset = browser->show_headers ? hpp_list->nr_header_lines : 0; ui_browser__gotorc(&browser->b, row + header_offset, column); }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo2945.31%133.33%
jiri olsajiri olsa2539.06%133.33%
arnaldo carvalho de melo* (jori olsa*?)arnaldo carvalho de melo* (jori olsa*?)1015.62%133.33%
Total64100.00%3100.00%


static void hist_browser__reset(struct hist_browser *browser) { /* * The hists__remove_entry_filter() already folds non-filtered * entries so we can assume it has 0 callchain rows. */ browser->nr_callchain_rows = 0; hist_browser__update_nr_entries(browser); browser->b.nr_entries = hist_browser__nr_entries(browser); hist_browser__refresh_dimensions(&browser->b); ui_browser__reset_index(&browser->b); }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo3570.00%360.00%
namhyung kimnamhyung kim1530.00%240.00%
Total50100.00%5100.00%


static char tree__folded_sign(bool unfolded) { return unfolded ? '-' : '+'; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo16100.00%1100.00%
Total16100.00%1100.00%


static char hist_entry__folded(const struct hist_entry *he) { return he->has_children ? tree__folded_sign(he->unfolded) : ' '; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo2180.77%150.00%
namhyung kimnamhyung kim519.23%150.00%
Total26100.00%2100.00%


static char callchain_list__folded(const struct callchain_list *cl) { return cl->has_children ? tree__folded_sign(cl->unfolded) : ' '; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo1869.23%266.67%
namhyung kimnamhyung kim830.77%133.33%
Total26100.00%3100.00%


static void callchain_list__set_folding(struct callchain_list *cl, bool unfold) { cl->unfolded = unfold ? cl->has_children : false; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo2180.77%150.00%
namhyung kimnamhyung kim519.23%150.00%
Total26100.00%2100.00%


static int callchain_node__count_rows_rb_tree(struct callchain_node *node) { int n = 0; struct rb_node *nd; for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); struct callchain_list *chain; char folded_sign = ' '; /* No children */ list_for_each_entry(chain, &child->val, list) { ++n; /* We need this because we may not have children */ folded_sign = callchain_list__folded(chain); if (folded_sign == '+') break; } if (folded_sign == '-') /* Have children and they're unfolded */ n += callchain_node__count_rows_rb_tree(child); } return n; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo115100.00%2100.00%
Total115100.00%2100.00%


static int callchain_node__count_flat_rows(struct callchain_node *node) { struct callchain_list *chain; char folded_sign = 0; int n = 0; list_for_each_entry(chain, &node->parent_val, list) { if (!folded_sign) { /* only check first chain list entry */ folded_sign = callchain_list__folded(chain); if (folded_sign == '+') return 1; } n++; } list_for_each_entry(chain, &node->val, list) { if (!folded_sign) { /* node->parent_val list might be empty */ folded_sign = callchain_list__folded(chain); if (folded_sign == '+') return 1; } n++; } return n; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim103100.00%1100.00%
Total103100.00%1100.00%


static int callchain_node__count_folded_rows(struct callchain_node *node __maybe_unused) { return 1; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim15100.00%1100.00%
Total15100.00%1100.00%


static int callchain_node__count_rows(struct callchain_node *node) { struct callchain_list *chain; bool unfolded = false; int n = 0; if (callchain_param.mode == CHAIN_FLAT) return callchain_node__count_flat_rows(node); else if (callchain_param.mode == CHAIN_FOLDED) return callchain_node__count_folded_rows(node); list_for_each_entry(chain, &node->val, list) { ++n; unfolded = chain->unfolded; } if (unfolded) n += callchain_node__count_rows_rb_tree(node); return n; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo5967.05%133.33%
namhyung kimnamhyung kim2932.95%266.67%
Total88100.00%3100.00%


static int callchain__count_rows(struct rb_root *chain) { struct rb_node *nd; int n = 0; for (nd = rb_first(chain); nd; nd = rb_next(nd)) { struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); n += callchain_node__count_rows(node); } return n; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo66100.00%1100.00%
Total66100.00%1100.00%


static int hierarchy_count_rows(struct hist_browser *hb, struct hist_entry *he, bool include_children) { int count = 0; struct rb_node *node; struct hist_entry *child; if (he->leaf) return callchain__count_rows(&he->sorted_chain); if (he->has_no_entry) return 1; node = rb_first(&he->hroot_out); while (node) { float percent; child = rb_entry(node, struct hist_entry, rb_node); percent = hist_entry__get_percent_limit(child); if (!child->filtered && percent >= hb->min_pcnt) { count++; if (include_children && child->unfolded) count += hierarchy_count_rows(hb, child, true); } node = rb_next(node); } return count; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim143100.00%2100.00%
Total143100.00%2100.00%


static bool hist_entry__toggle_fold(struct hist_entry *he) { if (!he) return false; if (!he->has_children) return false; he->unfolded = !he->unfolded; return true; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo2048.78%133.33%
namhyung kimnamhyung kim1434.15%133.33%
jiri olsajiri olsa717.07%133.33%
Total41100.00%3100.00%


static bool callchain_list__toggle_fold(struct callchain_list *cl) { if (!cl) return false; if (!cl->has_children) return false; cl->unfolded = !cl->unfolded; return true; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim3482.93%150.00%
arnaldo carvalho de meloarnaldo carvalho de melo717.07%150.00%
Total41100.00%2100.00%


static void callchain_node__init_have_children_rb_tree(struct callchain_node *node) { struct rb_node *nd = rb_first(&node->rb_root); for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); struct callchain_list *chain; bool first = true; list_for_each_entry(chain, &child->val, list) { if (first) { first = false; chain->has_children = chain->list.next != &child->val || !RB_EMPTY_ROOT(&child->rb_root); } else chain->has_children = chain->list.next == &child->val && !RB_EMPTY_ROOT(&child->rb_root); } callchain_node__init_have_children_rb_tree(child); } }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo146100.00%3100.00%
Total146100.00%3100.00%


static void callchain_node__init_have_children(struct callchain_node *node, bool has_sibling) { struct callchain_list *chain; chain = list_entry(node->val.next, struct callchain_list, list); chain->has_children = has_sibling; if (!list_empty(&node->val)) { chain = list_entry(node->val.prev, struct callchain_list, list); chain->has_children = !RB_EMPTY_ROOT(&node->rb_root); } callchain_node__init_have_children_rb_tree(node); }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim4652.27%233.33%
arnaldo carvalho de meloarnaldo carvalho de melo3742.05%350.00%
andres freundandres freund55.68%116.67%
Total88100.00%6100.00%


static void callchain__init_have_children(struct rb_root *root) { struct rb_node *nd = rb_first(root); bool has_sibling = nd && rb_next(nd); for (nd = rb_first(root); nd; nd = rb_next(nd)) { struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); callchain_node__init_have_children(node, has_sibling); if (callchain_param.mode == CHAIN_FLAT || callchain_param.mode == CHAIN_FOLDED) callchain_node__make_parent_list(node); } }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo5660.87%240.00%
namhyung kimnamhyung kim3639.13%360.00%
Total92100.00%5100.00%


static void hist_entry__init_have_children(struct hist_entry *he) { if (he->init_have_children) return; if (he->leaf) { he->has_children = !RB_EMPTY_ROOT(&he->sorted_chain); callchain__init_have_children(&he->sorted_chain); } else { he->has_children = !RB_EMPTY_ROOT(&he->hroot_out); } he->init_have_children = true; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo4565.22%375.00%
namhyung kimnamhyung kim2434.78%125.00%
Total69100.00%4100.00%


static bool hist_browser__toggle_fold(struct hist_browser *browser) { struct hist_entry *he = browser->he_selection; struct map_symbol *ms = browser->selection; struct callchain_list *cl = container_of(ms, struct callchain_list, ms); bool has_children; if (!he || !ms) return false; if (ms == &he->ms) has_children = hist_entry__toggle_fold(he); else has_children = callchain_list__toggle_fold(cl); if (has_children) { int child_rows = 0; hist_entry__init_have_children(he); browser->b.nr_entries -= he->nr_rows; if (he->leaf) browser->nr_callchain_rows -= he->nr_rows; else browser->nr_hierarchy_entries -= he->nr_rows; if (symbol_conf.report_hierarchy) child_rows = hierarchy_count_rows(browser, he, true); if (he->unfolded) { if (he->leaf) he->nr_rows = callchain__count_rows(&he->sorted_chain); else he->nr_rows = hierarchy_count_rows(browser, he, false); /* account grand children */ if (symbol_conf.report_hierarchy) browser->b.nr_entries += child_rows - he->nr_rows; if (!he->leaf && he->nr_rows == 0) { he->has_no_entry = true; he->nr_rows = 1; } } else { if (symbol_conf.report_hierarchy) browser->b.nr_entries -= child_rows - he->nr_rows; if (he->has_no_entry) he->has_no_entry = false; he->nr_rows = 0; } browser->b.nr_entries += he->nr_rows; if (he->leaf) browser->nr_callchain_rows += he->nr_rows; else browser->nr_hierarchy_entries += he->nr_rows; return true; } /* If it doesn't have children, no toggling performed */ return false; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim22471.57%457.14%
arnaldo carvalho de meloarnaldo carvalho de melo7824.92%228.57%
wang nanwang nan113.51%114.29%
Total313100.00%7100.00%


static int callchain_node__set_folding_rb_tree(struct callchain_node *node, bool unfold) { int n = 0; struct rb_node *nd; for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); struct callchain_list *chain; bool has_children = false; list_for_each_entry(chain, &child->val, list) { ++n; callchain_list__set_folding(chain, unfold); has_children = chain->has_children; } if (has_children) n += callchain_node__set_folding_rb_tree(child, unfold); } return n; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo11399.12%266.67%
namhyung kimnamhyung kim10.88%133.33%
Total114100.00%3100.00%


static int callchain_node__set_folding(struct callchain_node *node, bool unfold) { struct callchain_list *chain; bool has_children = false; int n = 0; list_for_each_entry(chain, &node->val, list) { ++n; callchain_list__set_folding(chain, unfold); has_children = chain->has_children; } if (has_children) n += callchain_node__set_folding_rb_tree(node, unfold); return n; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo7098.59%150.00%
namhyung kimnamhyung kim11.41%150.00%
Total71100.00%2100.00%


static int callchain__set_folding(struct rb_root *chain, bool unfold) { struct rb_node *nd; int n = 0; for (nd = rb_first(chain); nd; nd = rb_next(nd)) { struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); n += callchain_node__set_folding(node, unfold); } return n; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo71100.00%1100.00%
Total71100.00%1100.00%


static int hierarchy_set_folding(struct hist_browser *hb, struct hist_entry *he, bool unfold __maybe_unused) { float percent; struct rb_node *nd; struct hist_entry *child; int n = 0; for (nd = rb_first(&he->hroot_out); nd; nd = rb_next(nd)) { child = rb_entry(nd, struct hist_entry, rb_node); percent = hist_entry__get_percent_limit(child); if (!child->filtered && percent >= hb->min_pcnt) n++; } return n; }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim99100.00%1100.00%
Total99100.00%1100.00%


static void hist_entry__set_folding(struct hist_entry *he, struct hist_browser *hb, bool unfold) { hist_entry__init_have_children(he); he->unfolded = unfold ? he->has_children : false; if (he->has_children) { int n; if (he->leaf) n = callchain__set_folding(&he->sorted_chain, unfold); else n = hierarchy_set_folding(hb, he, unfold); he->nr_rows = unfold ? n : 0; } else he->nr_rows = 0; }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo5962.77%250.00%
namhyung kimnamhyung kim3537.23%250.00%
Total94100.00%4100.00%


static void __hist_browser__set_folding(struct hist_browser *browser, bool unfold) { struct rb_node *nd; struct hist_entry *he; double percent; nd = rb_first(&browser->hists->entries); while (nd) { he = rb_entry(nd, struct hist_entry, rb_node); /* set folding state even if it's currently folded */ nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD); hist_entry__set_folding(he, browser, unfold); percent = hist_entry__get_percent_limit(he); if (he->filtered || percent < browser->min_pcnt) continue; if (!he->depth || unfold) browser->nr_hierarchy_entries++; if (he->leaf) browser->nr_callchain_rows += he->nr_rows; else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { browser->nr_hierarchy_entries++; he->has_no_entry = true; he->nr_rows = 1; } else he->has_no_entry = false; } }

Contributors

PersonTokensPropCommitsCommitProp
namhyung kimnamhyung kim11469.09%360.00%
arnaldo carvalho de meloarnaldo carvalho de melo5130.91%240.00%
Total165100.00%5100.00%


static void hist_browser__set_folding(struct hist_browser *browser, bool unfold) { browser->nr_hierarchy_entries = 0; browser->nr_callchain_rows = 0; __hist_browser__set_folding(browser, unfold); browser->b.nr_entries = hist_browser__nr_entries(browser); /* Go to the start, we may be way after valid entries after a collapse */ ui_browser__reset_index(&browser->b); }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo3769.81%250.00%
namhyung kimnamhyung kim1630.19%250.00%
Total53100.00%4100.00%


static void ui_browser__warn_lost_events(struct ui_browser *browser) { ui_browser__warning(browser, 4, "Events are being lost, check IO/CPU overload!\n\n" "You may want to run 'perf' using a RT scheduler policy:\n\n" " perf top -r 80\n\n" "Or reduce the sampling frequency."); }

Contributors

PersonTokensPropCommitsCommitProp
arnaldo carvalho de meloarnaldo carvalho de melo23100.00%1100.00%
Total23100.00%1100.00%


static int hist_browser__title(struct hist_browser *browser, char *bf, size_t size) { return browser->title ? browser->title(browser, bf, size) : 0; }

Contributors

PersonTokensPropCommitsCommitProp
jiri olsajiri olsa36100.00%1100.00%
Total36100.00%1100.00%


int hist_browser__run(struct hist_browser *browser, const char *help) { int key; char title[160]; struct hist_browser_timer *hbt = browser->hbt; int delay_secs = hbt ? hbt->refresh : 0; browser->b.entries = &browser->hists->entries; browser->b