From 45d8e8025a2b2a6996be92d769fb6763bfb3cbae Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 3 Jun 2010 15:50:01 +0200 Subject: perf annotate: Ask objdump to demangle symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perf report is demangling symbols but not annotate. The former uses internal demangling via libbdf or libiberty. The latter executes objdump which by default does not demangle symbols. This patch adds the -C option to the objdump cmdline to enable symbol demangling. Cc: David S. Miller Cc: Frédéric Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Tom Zanussi LKML-Reference: <4c07b323.2126e30a.6245.0e1e@mx.google.com> Signed-off-by: Stephane Eranian Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 07f89b66b318..9e6baad92c4a 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1037,7 +1037,7 @@ fallback: dso, dso->long_name, sym, sym->name); snprintf(command, sizeof(command), - "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s|expand", + "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand", map__rip_2objdump(map, sym->start), map__rip_2objdump(map, sym->end), filename, filename); -- cgit v1.2.2 From f60f359383edf2a0ec3aa32cf8be98ad815bdf65 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Fri, 4 Jun 2010 11:27:10 -0300 Subject: perf report: Implement --sort cpu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a shared multi-core environment, users want to analyze why their program was slow. In particular, if the code ran slower only on certain CPUs due to interference from other programs or kernel threads, the user should be able to notice that. Sample usage: perf record -f -a -- sleep 3 perf report --sort cpu,comm Workload: program is running on 16 CPUs Experiencing interference from an antagonist only on 4 CPUs. Samples: 106218177676 cycles Overhead CPU Command ........ ... ............... 6.25% 2 program 6.24% 6 program 6.24% 11 program 6.24% 5 program 6.24% 9 program 6.24% 10 program 6.23% 15 program 6.23% 7 program 6.23% 3 program 6.23% 14 program 6.22% 1 program 6.20% 13 program 3.17% 12 program 3.15% 8 program 3.14% 0 program 3.13% 4 program 3.11% 4 antagonist 3.11% 0 antagonist 3.10% 8 antagonist 3.07% 12 antagonist Cc: David S. Miller Cc: Frédéric Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Tom Zanussi LKML-Reference: <20100505181612.GA5091@sharma-home.net> Signed-off-by: Arun Sharma Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 9e6baad92c4a..68d288c975de 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -70,6 +70,7 @@ struct hist_entry *__hists__add_entry(struct hists *self, .map = al->map, .sym = al->sym, }, + .cpu = al->cpu, .ip = al->addr, .level = al->level, .period = period, -- cgit v1.2.2 From cc5edb0eb9ce892b530e34a5d110382483587942 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 16 Jul 2010 12:35:07 -0300 Subject: perf hists: Factor out duplicated code Introducing hists__remove_entry_filter. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 68d288c975de..7b5848ce1505 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -795,6 +795,21 @@ enum hist_filter { HIST_FILTER__THREAD, }; +static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h, + enum hist_filter filter) +{ + h->filtered &= ~(1 << filter); + if (h->filtered) + return; + + ++self->nr_entries; + self->stats.total_period += h->period; + self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; + + if (h->ms.sym && self->max_sym_namelen < h->ms.sym->namelen) + self->max_sym_namelen = h->ms.sym->namelen; +} + void hists__filter_by_dso(struct hists *self, const struct dso *dso) { struct rb_node *nd; @@ -814,15 +829,7 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso) continue; } - h->filtered &= ~(1 << HIST_FILTER__DSO); - if (!h->filtered) { - ++self->nr_entries; - self->stats.total_period += h->period; - self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; - if (h->ms.sym && - self->max_sym_namelen < h->ms.sym->namelen) - self->max_sym_namelen = h->ms.sym->namelen; - } + hists__remove_entry_filter(self, h, HIST_FILTER__DSO); } } @@ -841,15 +848,8 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread) h->filtered |= (1 << HIST_FILTER__THREAD); continue; } - h->filtered &= ~(1 << HIST_FILTER__THREAD); - if (!h->filtered) { - ++self->nr_entries; - self->stats.total_period += h->period; - self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; - if (h->ms.sym && - self->max_sym_namelen < h->ms.sym->namelen) - self->max_sym_namelen = h->ms.sym->namelen; - } + + hists__remove_entry_filter(self, h, HIST_FILTER__THREAD); } } -- cgit v1.2.2 From 7a007ca90b7c465137de06795ef4d5faa10f459e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Jul 2010 09:19:41 -0300 Subject: perf hists: Mark entries filtered by parent And don't consider them in hists__inc_nr_entries. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 7b5848ce1505..d998d1d706eb 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -5,6 +5,12 @@ #include "sort.h" #include +enum hist_filter { + HIST_FILTER__DSO, + HIST_FILTER__THREAD, + HIST_FILTER__PARENT, +}; + struct callchain_param callchain_param = { .mode = CHAIN_GRAPH_REL, .min_percent = 0.5 @@ -52,11 +58,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry) { + if (entry->filtered) + return; if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen) self->max_sym_namelen = entry->ms.sym->namelen; ++self->nr_entries; } +static u8 symbol__parent_filter(const struct symbol *parent) +{ + if (symbol_conf.exclude_other && parent == NULL) + return 1 << HIST_FILTER__PARENT; + return 0; +} + struct hist_entry *__hists__add_entry(struct hists *self, struct addr_location *al, struct symbol *sym_parent, u64 period) @@ -75,6 +90,7 @@ struct hist_entry *__hists__add_entry(struct hists *self, .level = al->level, .period = period, .parent = sym_parent, + .filtered = symbol__parent_filter(sym_parent), }; int cmp; @@ -790,11 +806,6 @@ print_entries: return ret; } -enum hist_filter { - HIST_FILTER__DSO, - HIST_FILTER__THREAD, -}; - static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h, enum hist_filter filter) { -- cgit v1.2.2 From 8a6c5b261c1188379469807d84bfb1365d0f6823 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 20 Jul 2010 14:42:52 -0300 Subject: perf sort: Make column width code per hists instance They were globals, and since we support multiple hists and sessions at the same time, it doesn't make sense to calculate those values considereing all symbols in all sessions. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 115 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 36 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index d998d1d706eb..0bc67900352c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -16,6 +16,50 @@ struct callchain_param callchain_param = { .min_percent = 0.5 }; +u16 hists__col_len(struct hists *self, enum hist_column col) +{ + return self->col_len[col]; +} + +void hists__set_col_len(struct hists *self, enum hist_column col, u16 len) +{ + self->col_len[col] = len; +} + +bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len) +{ + if (len > hists__col_len(self, col)) { + hists__set_col_len(self, col, len); + return true; + } + return false; +} + +static void hists__reset_col_len(struct hists *self) +{ + enum hist_column col; + + for (col = 0; col < HISTC_NR_COLS; ++col) + hists__set_col_len(self, col, 0); +} + +static void hists__calc_col_len(struct hists *self, struct hist_entry *h) +{ + u16 len; + + if (h->ms.sym) + hists__new_col_len(self, HISTC_SYMBOL, h->ms.sym->namelen); + + len = thread__comm_len(h->thread); + if (hists__new_col_len(self, HISTC_COMM, len)) + hists__set_col_len(self, HISTC_THREAD, len + 6); + + if (h->ms.map) { + len = dso__name_len(h->ms.map->dso); + hists__new_col_len(self, HISTC_DSO, len); + } +} + static void hist_entry__add_cpumode_period(struct hist_entry *self, unsigned int cpumode, u64 period) { @@ -56,13 +100,12 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) return self; } -static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry) +static void hists__inc_nr_entries(struct hists *self, struct hist_entry *h) { - if (entry->filtered) - return; - if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen) - self->max_sym_namelen = entry->ms.sym->namelen; - ++self->nr_entries; + if (!h->filtered) { + hists__calc_col_len(self, h); + ++self->nr_entries; + } } static u8 symbol__parent_filter(const struct symbol *parent) @@ -208,7 +251,7 @@ void hists__collapse_resort(struct hists *self) tmp = RB_ROOT; next = rb_first(&self->entries); self->nr_entries = 0; - self->max_sym_namelen = 0; + hists__reset_col_len(self); while (next) { n = rb_entry(next, struct hist_entry, rb_node); @@ -265,7 +308,7 @@ void hists__output_resort(struct hists *self) next = rb_first(&self->entries); self->nr_entries = 0; - self->max_sym_namelen = 0; + hists__reset_col_len(self); while (next) { n = rb_entry(next, struct hist_entry, rb_node); @@ -532,8 +575,9 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, } int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, - struct hists *pair_hists, bool show_displacement, - long displacement, bool color, u64 session_total) + struct hists *hists, struct hists *pair_hists, + bool show_displacement, long displacement, + bool color, u64 session_total) { struct sort_entry *se; u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; @@ -637,24 +681,25 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, ret += snprintf(s + ret, size - ret, "%s", sep ?: " "); ret += se->se_snprintf(self, s + ret, size - ret, - se->se_width ? *se->se_width : 0); + hists__col_len(hists, se->se_width_idx)); } return ret; } -int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists, - bool show_displacement, long displacement, FILE *fp, - u64 session_total) +int hist_entry__fprintf(struct hist_entry *self, struct hists *hists, + struct hists *pair_hists, bool show_displacement, + long displacement, FILE *fp, u64 session_total) { char bf[512]; - hist_entry__snprintf(self, bf, sizeof(bf), pair_hists, + hist_entry__snprintf(self, bf, sizeof(bf), hists, pair_hists, show_displacement, displacement, true, session_total); return fprintf(fp, "%s\n", bf); } -static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, +static size_t hist_entry__fprintf_callchain(struct hist_entry *self, + struct hists *hists, FILE *fp, u64 session_total) { int left_margin = 0; @@ -662,7 +707,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, if (sort__first_dimension == SORT_COMM) { struct sort_entry *se = list_first_entry(&hist_entry__sort_list, typeof(*se), list); - left_margin = se->se_width ? *se->se_width : 0; + left_margin = hists__col_len(hists, se->se_width_idx); left_margin -= thread__comm_len(self->thread); } @@ -733,17 +778,17 @@ size_t hists__fprintf(struct hists *self, struct hists *pair, continue; } width = strlen(se->se_header); - if (se->se_width) { - if (symbol_conf.col_width_list_str) { - if (col_width) { - *se->se_width = atoi(col_width); - col_width = strchr(col_width, ','); - if (col_width) - ++col_width; - } + if (symbol_conf.col_width_list_str) { + if (col_width) { + hists__set_col_len(self, se->se_width_idx, + atoi(col_width)); + col_width = strchr(col_width, ','); + if (col_width) + ++col_width; } - width = *se->se_width = max(*se->se_width, width); } + if (!hists__new_col_len(self, se->se_width_idx, width)) + width = hists__col_len(self, se->se_width_idx); fprintf(fp, " %*s", width, se->se_header); } fprintf(fp, "\n"); @@ -766,9 +811,8 @@ size_t hists__fprintf(struct hists *self, struct hists *pair, continue; fprintf(fp, " "); - if (se->se_width) - width = *se->se_width; - else + width = hists__col_len(self, se->se_width_idx); + if (width == 0) width = strlen(se->se_header); for (i = 0; i < width; i++) fprintf(fp, "."); @@ -788,12 +832,12 @@ print_entries: displacement = 0; ++position; } - ret += hist_entry__fprintf(h, pair, show_displacement, + ret += hist_entry__fprintf(h, self, pair, show_displacement, displacement, fp, self->stats.total_period); if (symbol_conf.use_callchain) - ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period); - + ret += hist_entry__fprintf_callchain(h, self, fp, + self->stats.total_period); if (h->ms.map == NULL && verbose > 1) { __map_groups__fprintf_maps(&h->thread->mg, MAP__FUNCTION, verbose, fp); @@ -817,8 +861,7 @@ static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h, self->stats.total_period += h->period; self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; - if (h->ms.sym && self->max_sym_namelen < h->ms.sym->namelen) - self->max_sym_namelen = h->ms.sym->namelen; + hists__calc_col_len(self, h); } void hists__filter_by_dso(struct hists *self, const struct dso *dso) @@ -827,7 +870,7 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso) self->nr_entries = self->stats.total_period = 0; self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; - self->max_sym_namelen = 0; + hists__reset_col_len(self); for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); @@ -850,7 +893,7 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread) self->nr_entries = self->stats.total_period = 0; self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; - self->max_sym_namelen = 0; + hists__reset_col_len(self); for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); -- cgit v1.2.2 From 06daaaba7c211ca6a8227b9a54dbc86dd837f034 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 21 Jul 2010 17:58:25 -0300 Subject: perf hist: Introduce routine to measure lenght of formatted entry Will be used to figure out the window width needed in the new tree widget. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0bc67900352c..f93095ffaab0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -850,6 +850,33 @@ print_entries: return ret; } +/* + * See hists__fprintf to match the column widths + */ +unsigned int hists__sort_list_width(struct hists *self) +{ + struct sort_entry *se; + int ret = 9; /* total % */ + + if (symbol_conf.show_cpu_utilization) { + ret += 7; /* count_sys % */ + ret += 6; /* count_us % */ + if (perf_guest) { + ret += 13; /* count_guest_sys % */ + ret += 12; /* count_guest_us % */ + } + } + + if (symbol_conf.show_nr_samples) + ret += 11; + + list_for_each_entry(se, &hist_entry__sort_list, list) + if (!se->elide) + ret += 2 + hists__col_len(self, se->se_width_idx); + + return ret; +} + static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h, enum hist_filter filter) { -- cgit v1.2.2 From 0f0cbf7aa3d3460a3eb201a772326739a0c0210a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 26 Jul 2010 17:13:40 -0300 Subject: perf ui: New hists tree widget The stock newt checkbox tree widget we were using was not really suitable for hist entry + callchain browsing. The problems with it were manifold: - We needed to traverse the whole hist_entry rb_tree to add each entry + callchains beforehand. - No control over the colors used for each row So a new tree widget, based mostly on slang, was written. It extends the ui_browser class already used for annotate to allow the user to fold/unfold branches in the callchains tree, using extra fields in the symbol_map class that is embedded in hist_entry and callchain_node instances to store the folding state and when changing this state calculates the number of rows that are produced when showing a particular hist_entry instance. This greatly speeds up browsing as we don't have to upfront touch all the entries and only calculate callchain related operations when some callchain branch is actually unfolded. The memory footprint is also reduced as the data structure is not duplicated, just some extra fields for controling callchain state and to simplify the process of seeking thru entries (nr_rows, row_offset) were added. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f93095ffaab0..d0f07f7bdf16 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -885,6 +885,9 @@ static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h, return; ++self->nr_entries; + if (h->ms.unfolded) + self->nr_entries += h->nr_rows; + h->row_offset = 0; self->stats.total_period += h->period; self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; -- cgit v1.2.2 From 0a1eae391d0d92b60cff9f55cdaf3861b4e33922 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Aug 2010 19:45:23 -0300 Subject: perf tools: Don't keep unreferenced maps when unmaps are detected For a file with: [root@emilia linux-2.6-tip]# perf report -D -fi allmodconfig-j32.perf.data | grep events: TOTAL events: 36933 MMAP events: 9056 LOST events: 0 COMM events: 1702 EXIT events: 1887 THROTTLE events: 8 UNTHROTTLE events: 8 FORK events: 1894 READ events: 0 SAMPLE events: 22378 ATTR events: 0 EVENT_TYPE events: 0 TRACING_DATA events: 0 BUILD_ID events: 0 [root@emilia linux-2.6-tip]# Testing with valgrind and making perf_session__delete() a nop, so that we can notice how many maps were actually deleted due to not having any samples on it: ==== HEAP SUMMARY: Before: ==10339== in use at exit: 8,909,997 bytes in 68,690 blocks ==10339== total heap usage: 78,696 allocs, 10,007 frees, 11,925,853 bytes allocated After: ==10506== in use at exit: 8,902,605 bytes in 68,606 blocks ==10506== total heap usage: 78,696 allocs, 10,091 frees, 11,925,853 bytes allocated I.e. just 84 detected unmaps with no hits out of 9056 for this workload, not much, but in some other long running workload this may save more bytes. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index a6cea2894d12..e7263d49bcf0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -93,6 +93,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) if (self != NULL) { *self = *template; self->nr_events = 1; + if (self->ms.map) + self->ms.map->referenced = true; if (symbol_conf.use_callchain) callchain_init(self->callchain); } -- cgit v1.2.2 From 903cce6eb9117550755de9bf92f3b48367b7dfe0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 5 Aug 2010 19:15:48 -0300 Subject: perf hists: Handle verbose in hists__sort_list_width Otherwise entries will get chopped up on the window. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e7263d49bcf0..62ec9b0e4b9a 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -876,6 +876,9 @@ unsigned int hists__sort_list_width(struct hists *self) if (!se->elide) ret += 2 + hists__col_len(self, se->se_width_idx); + if (verbose) /* Addr + origin */ + ret += 3 + BITS_PER_LONG / 4; + return ret; } -- cgit v1.2.2 From 92221162875ec48913d3f9710046e48d599c9cf2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 9 Aug 2010 15:30:40 -0300 Subject: perf annotate: Sort by hottest lines in the TUI Right now it will just sort and position at the hottest line, i.e. the one where more samples were taken. It will be at the center of the screen and later TAB/shift-TAB will cycle thru the hottest lines. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 62ec9b0e4b9a..be22ae6ef055 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -983,9 +983,9 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip) return 0; } -static struct objdump_line *objdump_line__new(s64 offset, char *line) +static struct objdump_line *objdump_line__new(s64 offset, char *line, size_t privsize) { - struct objdump_line *self = malloc(sizeof(*self)); + struct objdump_line *self = malloc(sizeof(*self) + privsize); if (self != NULL) { self->offset = offset; @@ -1017,7 +1017,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, } static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file, - struct list_head *head) + struct list_head *head, size_t privsize) { struct symbol *sym = self->ms.sym; struct objdump_line *objdump_line; @@ -1068,7 +1068,7 @@ static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file, offset = -1; } - objdump_line = objdump_line__new(offset, line); + objdump_line = objdump_line__new(offset, line, privsize); if (objdump_line == NULL) { free(line); return -1; @@ -1078,7 +1078,8 @@ static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file, return 0; } -int hist_entry__annotate(struct hist_entry *self, struct list_head *head) +int hist_entry__annotate(struct hist_entry *self, struct list_head *head, + size_t privsize) { struct symbol *sym = self->ms.sym; struct map *map = self->ms.map; @@ -1143,7 +1144,7 @@ fallback: goto out_free_filename; while (!feof(file)) - if (hist_entry__parse_objdump_line(self, file, head) < 0) + if (hist_entry__parse_objdump_line(self, file, head, privsize) < 0) break; pclose(file); -- cgit v1.2.2