summaryrefslogtreecommitdiffstats
path: root/tools/perf/ui
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/ui')
-rw-r--r--tools/perf/ui/browser.c4
-rw-r--r--tools/perf/ui/browser.h1
-rw-r--r--tools/perf/ui/browsers/annotate.c42
-rw-r--r--tools/perf/ui/browsers/header.c2
-rw-r--r--tools/perf/ui/browsers/hists.c445
-rw-r--r--tools/perf/ui/browsers/hists.h4
-rw-r--r--tools/perf/ui/browsers/map.c2
-rw-r--r--tools/perf/ui/browsers/res_sample.c11
-rw-r--r--tools/perf/ui/browsers/scripts.c21
-rw-r--r--tools/perf/ui/gtk/Build7
-rw-r--r--tools/perf/ui/gtk/annotate.c32
-rw-r--r--tools/perf/ui/gtk/browser.c2
-rw-r--r--tools/perf/ui/gtk/gtk.h8
-rw-r--r--tools/perf/ui/gtk/helpline.c2
-rw-r--r--tools/perf/ui/gtk/hists.c8
-rw-r--r--tools/perf/ui/gtk/progress.c1
-rw-r--r--tools/perf/ui/gtk/setup.c4
-rw-r--r--tools/perf/ui/gtk/util.c2
-rw-r--r--tools/perf/ui/helpline.c2
-rw-r--r--tools/perf/ui/helpline.h2
-rw-r--r--tools/perf/ui/hist.c21
-rw-r--r--tools/perf/ui/progress.c1
-rw-r--r--tools/perf/ui/setup.c7
-rw-r--r--tools/perf/ui/stdio/hist.c36
-rw-r--r--tools/perf/ui/tui/helpline.c3
-rw-r--r--tools/perf/ui/tui/progress.c1
-rw-r--r--tools/perf/ui/tui/setup.c5
-rw-r--r--tools/perf/ui/tui/util.c51
-rw-r--r--tools/perf/ui/util.c4
-rw-r--r--tools/perf/ui/util.h4
30 files changed, 495 insertions, 240 deletions
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index d227d74b28f8..781afe42e90e 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
-#include "../util/util.h"
#include "../util/string2.h"
#include "../util/config.h"
-#include "../perf.h"
#include "libslang.h"
#include "ui.h"
#include "util.h"
@@ -347,6 +345,8 @@ static int __ui_browser__refresh(struct ui_browser *browser)
SLsmg_fill_region(browser->y + row + browser->extra_title_lines, browser->x,
browser->rows - row, width, ' ');
+ if (browser->nr_entries == 0 && browser->no_samples_msg)
+ __ui__info_window(NULL, browser->no_samples_msg, NULL);
return 0;
}
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index dc1444136658..3678eb88f119 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -23,6 +23,7 @@ struct ui_browser {
void *priv;
const char *title;
char *helpline;
+ const char *no_samples_msg;
void (*refresh_dimensions)(struct ui_browser *browser);
unsigned int (*refresh)(struct ui_browser *browser);
void (*write)(struct ui_browser *browser, void *entry, int row);
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index e67880bf1efe..badbddbb30f8 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -2,8 +2,9 @@
#include "../browser.h"
#include "../helpline.h"
#include "../ui.h"
-#include "../util.h"
#include "../../util/annotate.h"
+#include "../../util/debug.h"
+#include "../../util/dso.h"
#include "../../util/hist.h"
#include "../../util/sort.h"
#include "../../util/map.h"
@@ -299,7 +300,7 @@ static void annotate_browser__set_rb_top(struct annotate_browser *browser,
}
static void annotate_browser__calc_percent(struct annotate_browser *browser,
- struct perf_evsel *evsel)
+ struct evsel *evsel)
{
struct map_symbol *ms = browser->b.priv;
struct symbol *sym = ms->sym;
@@ -406,10 +407,10 @@ static int sym_title(struct symbol *sym, struct map *map, char *title,
* to the calling function.
*/
static bool annotate_browser__callq(struct annotate_browser *browser,
- struct perf_evsel *evsel,
+ struct evsel *evsel,
struct hist_browser_timer *hbt)
{
- struct map_symbol *ms = browser->b.priv;
+ struct map_symbol *ms = browser->b.priv, target_ms;
struct disasm_line *dl = disasm_line(browser->selection);
struct annotation *notes;
char title[SYM_TITLE_MAX_SIZE];
@@ -422,15 +423,18 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
notes = symbol__annotation(dl->ops.target.sym);
pthread_mutex_lock(&notes->lock);
- if (!symbol__hists(dl->ops.target.sym, evsel->evlist->nr_entries)) {
+ if (!symbol__hists(dl->ops.target.sym, evsel->evlist->core.nr_entries)) {
pthread_mutex_unlock(&notes->lock);
ui__warning("Not enough memory for annotating '%s' symbol!\n",
dl->ops.target.sym->name);
return true;
}
+ target_ms.maps = ms->maps;
+ target_ms.map = ms->map;
+ target_ms.sym = dl->ops.target.sym;
pthread_mutex_unlock(&notes->lock);
- symbol__tui_annotate(dl->ops.target.sym, ms->map, evsel, hbt, browser->opts);
+ symbol__tui_annotate(&target_ms, evsel, hbt, browser->opts);
sym_title(ms->sym, ms->map, title, sizeof(title), browser->opts->percent_type);
ui_browser__show_title(&browser->b, title);
return true;
@@ -455,7 +459,7 @@ struct disasm_line *annotate_browser__find_offset(struct annotate_browser *brows
}
static bool annotate_browser__jump(struct annotate_browser *browser,
- struct perf_evsel *evsel,
+ struct evsel *evsel,
struct hist_browser_timer *hbt)
{
struct disasm_line *dl = disasm_line(browser->selection);
@@ -656,7 +660,7 @@ switch_percent_type(struct annotation_options *opts, bool base)
}
static int annotate_browser__run(struct annotate_browser *browser,
- struct perf_evsel *evsel,
+ struct evsel *evsel,
struct hist_browser_timer *hbt)
{
struct rb_node *nd = NULL;
@@ -869,14 +873,14 @@ out:
return key;
}
-int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel,
+int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
struct hist_browser_timer *hbt,
struct annotation_options *opts)
{
- return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt, opts);
+ return symbol__tui_annotate(ms, evsel, hbt, opts);
}
-int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
+int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel,
struct hist_browser_timer *hbt,
struct annotation_options *opts)
{
@@ -887,16 +891,12 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
return map_symbol__tui_annotate(&he->ms, evsel, hbt, opts);
}
-int symbol__tui_annotate(struct symbol *sym, struct map *map,
- struct perf_evsel *evsel,
+int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
struct hist_browser_timer *hbt,
struct annotation_options *opts)
{
+ struct symbol *sym = ms->sym;
struct annotation *notes = symbol__annotation(sym);
- struct map_symbol ms = {
- .map = map,
- .sym = sym,
- };
struct annotate_browser browser = {
.b = {
.refresh = annotate_browser__refresh,
@@ -904,7 +904,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
.write = annotate_browser__write,
.filter = disasm_line__filter,
.extra_title_lines = 1, /* for hists__scnprintf_title() */
- .priv = &ms,
+ .priv = ms,
.use_navkeypressed = true,
},
.opts = opts,
@@ -914,13 +914,13 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
if (sym == NULL)
return -1;
- if (map->dso->annotate_warned)
+ if (ms->map->dso->annotate_warned)
return -1;
- err = symbol__annotate2(sym, map, evsel, opts, &browser.arch);
+ err = symbol__annotate2(ms, evsel, opts, &browser.arch);
if (err) {
char msg[BUFSIZ];
- symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
+ symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
goto out_free_offsets;
}
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c
index 5aeb663dd184..57e6e4332f74 100644
--- a/tools/perf/ui/browsers/header.c
+++ b/tools/perf/ui/browsers/header.c
@@ -1,6 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-#include "util/cache.h"
-#include "util/debug.h"
#include "ui/browser.h"
#include "ui/keysyms.h"
#include "ui/ui.h"
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a94eb0755e8b..f36dee499320 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -11,17 +11,26 @@
#include <linux/time64.h>
#include <linux/zalloc.h>
+#include "../../util/debug.h"
+#include "../../util/dso.h"
#include "../../util/callchain.h"
#include "../../util/evsel.h"
#include "../../util/evlist.h"
+#include "../../util/header.h"
#include "../../util/hist.h"
+#include "../../util/machine.h"
#include "../../util/map.h"
+#include "../../util/maps.h"
#include "../../util/symbol.h"
+#include "../../util/map_symbol.h"
+#include "../../util/branch.h"
#include "../../util/pstack.h"
#include "../../util/sort.h"
#include "../../util/top.h"
#include "../../util/thread.h"
+#include "../../util/block-info.h"
#include "../../arch/common.h"
+#include "../../perf.h"
#include "../browsers/hists.h"
#include "../helpline.h"
@@ -384,6 +393,57 @@ static void hist_entry__init_have_children(struct hist_entry *he)
he->init_have_children = true;
}
+static bool hist_browser__selection_has_children(struct hist_browser *browser)
+{
+ struct hist_entry *he = browser->he_selection;
+ struct map_symbol *ms = browser->selection;
+
+ if (!he || !ms)
+ return false;
+
+ if (ms == &he->ms)
+ return he->has_children;
+
+ return container_of(ms, struct callchain_list, ms)->has_children;
+}
+
+static bool hist_browser__he_selection_unfolded(struct hist_browser *browser)
+{
+ return browser->he_selection ? browser->he_selection->unfolded : false;
+}
+
+static bool hist_browser__selection_unfolded(struct hist_browser *browser)
+{
+ struct hist_entry *he = browser->he_selection;
+ struct map_symbol *ms = browser->selection;
+
+ if (!he || !ms)
+ return false;
+
+ if (ms == &he->ms)
+ return he->unfolded;
+
+ return container_of(ms, struct callchain_list, ms)->unfolded;
+}
+
+static char *hist_browser__selection_sym_name(struct hist_browser *browser, char *bf, size_t size)
+{
+ struct hist_entry *he = browser->he_selection;
+ struct map_symbol *ms = browser->selection;
+ struct callchain_list *callchain_entry;
+
+ if (!he || !ms)
+ return NULL;
+
+ if (ms == &he->ms) {
+ hist_entry__sym_snprintf(he, bf, size, 0);
+ return bf + 4; // skip the level, e.g. '[k] '
+ }
+
+ callchain_entry = container_of(ms, struct callchain_list, ms);
+ return callchain_list__sym_name(callchain_entry, bf, size, browser->show_dso);
+}
+
static bool hist_browser__toggle_fold(struct hist_browser *browser)
{
struct hist_entry *he = browser->he_selection;
@@ -617,10 +677,81 @@ static int hist_browser__title(struct hist_browser *browser, char *bf, size_t si
return browser->title ? browser->title(browser, bf, size) : 0;
}
+static int hist_browser__handle_hotkey(struct hist_browser *browser, bool warn_lost_event, char *title, int key)
+{
+ switch (key) {
+ case K_TIMER: {
+ struct hist_browser_timer *hbt = browser->hbt;
+ u64 nr_entries;
+
+ WARN_ON_ONCE(!hbt);
+
+ if (hbt)
+ hbt->timer(hbt->arg);
+
+ if (hist_browser__has_filter(browser) || symbol_conf.report_hierarchy)
+ hist_browser__update_nr_entries(browser);
+
+ nr_entries = hist_browser__nr_entries(browser);
+ ui_browser__update_nr_entries(&browser->b, nr_entries);
+
+ if (warn_lost_event &&
+ (browser->hists->stats.nr_lost_warned !=
+ browser->hists->stats.nr_events[PERF_RECORD_LOST])) {
+ browser->hists->stats.nr_lost_warned =
+ browser->hists->stats.nr_events[PERF_RECORD_LOST];
+ ui_browser__warn_lost_events(&browser->b);
+ }
+
+ hist_browser__title(browser, title, sizeof(title));
+ ui_browser__show_title(&browser->b, title);
+ break;
+ }
+ case 'D': { /* Debug */
+ struct hist_entry *h = rb_entry(browser->b.top, struct hist_entry, rb_node);
+ static int seq;
+
+ ui_helpline__pop();
+ ui_helpline__fpush("%d: nr_ent=(%d,%d), etl: %d, rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
+ seq++, browser->b.nr_entries, browser->hists->nr_entries,
+ browser->b.extra_title_lines, browser->b.rows,
+ browser->b.index, browser->b.top_idx, h->row_offset, h->nr_rows);
+ }
+ break;
+ case 'C':
+ /* Collapse the whole world. */
+ hist_browser__set_folding(browser, false);
+ break;
+ case 'c':
+ /* Collapse the selected entry. */
+ hist_browser__set_folding_selected(browser, false);
+ break;
+ case 'E':
+ /* Expand the whole world. */
+ hist_browser__set_folding(browser, true);
+ break;
+ case 'e':
+ /* Expand the selected entry. */
+ hist_browser__set_folding_selected(browser, !hist_browser__he_selection_unfolded(browser));
+ break;
+ case 'H':
+ browser->show_headers = !browser->show_headers;
+ hist_browser__update_rows(browser);
+ break;
+ case '+':
+ if (hist_browser__toggle_fold(browser))
+ break;
+ /* fall thru */
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
int hist_browser__run(struct hist_browser *browser, const char *help,
- bool warn_lost_event)
+ bool warn_lost_event, int key)
{
- int key;
char title[160];
struct hist_browser_timer *hbt = browser->hbt;
int delay_secs = hbt ? hbt->refresh : 0;
@@ -633,79 +764,14 @@ int hist_browser__run(struct hist_browser *browser, const char *help,
if (ui_browser__show(&browser->b, title, "%s", help) < 0)
return -1;
+ if (key && hist_browser__handle_hotkey(browser, warn_lost_event, title, key))
+ goto out;
+
while (1) {
key = ui_browser__run(&browser->b, delay_secs);
- switch (key) {
- case K_TIMER: {
- u64 nr_entries;
-
- WARN_ON_ONCE(!hbt);
-
- if (hbt)
- hbt->timer(hbt->arg);
-
- if (hist_browser__has_filter(browser) ||
- symbol_conf.report_hierarchy)
- hist_browser__update_nr_entries(browser);
-
- nr_entries = hist_browser__nr_entries(browser);
- ui_browser__update_nr_entries(&browser->b, nr_entries);
-
- if (warn_lost_event &&
- (browser->hists->stats.nr_lost_warned !=
- browser->hists->stats.nr_events[PERF_RECORD_LOST])) {
- browser->hists->stats.nr_lost_warned =
- browser->hists->stats.nr_events[PERF_RECORD_LOST];
- ui_browser__warn_lost_events(&browser->b);
- }
-
- hist_browser__title(browser, title, sizeof(title));
- ui_browser__show_title(&browser->b, title);
- continue;
- }
- case 'D': { /* Debug */
- static int seq;
- struct hist_entry *h = rb_entry(browser->b.top,
- struct hist_entry, rb_node);
- ui_helpline__pop();
- ui_helpline__fpush("%d: nr_ent=(%d,%d), etl: %d, rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
- seq++, browser->b.nr_entries,
- browser->hists->nr_entries,
- browser->b.extra_title_lines,
- browser->b.rows,
- browser->b.index,
- browser->b.top_idx,
- h->row_offset, h->nr_rows);
- }
- break;
- case 'C':
- /* Collapse the whole world. */
- hist_browser__set_folding(browser, false);
- break;
- case 'c':
- /* Collapse the selected entry. */
- hist_browser__set_folding_selected(browser, false);
- break;
- case 'E':
- /* Expand the whole world. */
- hist_browser__set_folding(browser, true);
- break;
- case 'e':
- /* Expand the selected entry. */
- hist_browser__set_folding_selected(browser, true);
+ if (hist_browser__handle_hotkey(browser, warn_lost_event, title, key))
break;
- case 'H':
- browser->show_headers = !browser->show_headers;
- hist_browser__update_rows(browser);
- break;
- case K_ENTER:
- if (hist_browser__toggle_fold(browser))
- break;
- /* fall thru */
- default:
- goto out;
- }
}
out:
ui_browser__hide(&browser->b);
@@ -1777,7 +1843,11 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
continue;
}
- percent = hist_entry__get_percent_limit(h);
+ if (symbol_conf.report_individual_block)
+ percent = block_info__total_cycles_percent(h);
+ else
+ percent = hist_entry__get_percent_limit(h);
+
if (percent < hb->min_pcnt)
continue;
@@ -2187,7 +2257,7 @@ struct hist_browser *hist_browser__new(struct hists *hists)
}
static struct hist_browser *
-perf_evsel_browser__new(struct perf_evsel *evsel,
+perf_evsel_browser__new(struct evsel *evsel,
struct hist_browser_timer *hbt,
struct perf_env *env,
struct annotation_options *annotation_opts)
@@ -2328,7 +2398,7 @@ close_file_and_continue:
closedir(pwd_dir);
if (nr_options) {
- choice = ui__popup_menu(nr_options, options);
+ choice = ui__popup_menu(nr_options, options, NULL);
if (choice < nr_options && choice >= 0) {
tmp = strdup(abs_path[choice]);
if (tmp) {
@@ -2352,7 +2422,7 @@ struct popup_action {
struct thread *thread;
struct map_symbol ms;
int socket;
- struct perf_evsel *evsel;
+ struct evsel *evsel;
enum rstype rstype;
int (*fn)(struct hist_browser *browser, struct popup_action *act);
@@ -2361,7 +2431,7 @@ struct popup_action {
static int
do_annotate(struct hist_browser *browser, struct popup_action *act)
{
- struct perf_evsel *evsel;
+ struct evsel *evsel;
struct annotation *notes;
struct hist_entry *he;
int err;
@@ -2374,7 +2444,11 @@ do_annotate(struct hist_browser *browser, struct popup_action *act)
if (!notes->src)
return 0;
- evsel = hists_to_evsel(browser->hists);
+ if (browser->block_evsel)
+ evsel = browser->block_evsel;
+ else
+ evsel = hists_to_evsel(browser->hists);
+
err = map_symbol__tui_annotate(&act->ms, evsel, browser->hbt,
browser->annotation_opts);
he = hist_browser__selected_entry(browser);
@@ -2394,16 +2468,16 @@ do_annotate(struct hist_browser *browser, struct popup_action *act)
static int
add_annotate_opt(struct hist_browser *browser __maybe_unused,
struct popup_action *act, char **optstr,
- struct map *map, struct symbol *sym)
+ struct map_symbol *ms)
{
- if (sym == NULL || map->dso->annotate_warned)
+ if (ms->sym == NULL || ms->map->dso->annotate_warned ||
+ symbol__annotation(ms->sym)->src == NULL)
return 0;
- if (asprintf(optstr, "Annotate %s", sym->name) < 0)
+ if (asprintf(optstr, "Annotate %s", ms->sym->name) < 0)
return 0;
- act->ms.map = map;
- act->ms.sym = sym;
+ act->ms = *ms;
act->fn = do_annotate;
return 1;
}
@@ -2470,11 +2544,8 @@ add_thread_opt(struct hist_browser *browser, struct popup_action *act,
return 1;
}
-static int
-do_zoom_dso(struct hist_browser *browser, struct popup_action *act)
+static int hists_browser__zoom_map(struct hist_browser *browser, struct map *map)
{
- struct map *map = act->ms.map;
-
if (!hists__has(browser->hists, dso) || map == NULL)
return 0;
@@ -2497,13 +2568,19 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act)
}
static int
+do_zoom_dso(struct hist_browser *browser, struct popup_action *act)
+{
+ return hists_browser__zoom_map(browser, act->ms.map);
+}
+
+static int
add_dso_opt(struct hist_browser *browser, struct popup_action *act,
char **optstr, struct map *map)
{
if (!hists__has(browser->hists, dso) || map == NULL)
return 0;
- if (asprintf(optstr, "Zoom %s %s DSO",
+ if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly into the kernel)",
browser->hists->dso_filter ? "out of" : "into",
__map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0)
return 0;
@@ -2513,6 +2590,28 @@ add_dso_opt(struct hist_browser *browser, struct popup_action *act,
return 1;
}
+static int do_toggle_callchain(struct hist_browser *browser, struct popup_action *act __maybe_unused)
+{
+ hist_browser__toggle_fold(browser);
+ return 0;
+}
+
+static int add_callchain_toggle_opt(struct hist_browser *browser, struct popup_action *act, char **optstr)
+{
+ char sym_name[512];
+
+ if (!hist_browser__selection_has_children(browser))
+ return 0;
+
+ if (asprintf(optstr, "%s [%s] callchain (one level, same as '+' hotkey, use 'e'/'c' for the whole main level entry)",
+ hist_browser__selection_unfolded(browser) ? "Collapse" : "Expand",
+ hist_browser__selection_sym_name(browser, sym_name, sizeof(sym_name))) < 0)
+ return 0;
+
+ act->fn = do_toggle_callchain;
+ return 1;
+}
+
static int
do_browse_map(struct hist_browser *browser __maybe_unused,
struct popup_action *act)
@@ -2596,7 +2695,7 @@ static int
add_script_opt_2(struct hist_browser *browser __maybe_unused,
struct popup_action *act, char **optstr,
struct thread *thread, struct symbol *sym,
- struct perf_evsel *evsel, const char *tstr)
+ struct evsel *evsel, const char *tstr)
{
if (thread) {
@@ -2623,7 +2722,7 @@ static int
add_script_opt(struct hist_browser *browser,
struct popup_action *act, char **optstr,
struct thread *thread, struct symbol *sym,
- struct perf_evsel *evsel)
+ struct evsel *evsel)
{
int n, j;
struct hist_entry *he;
@@ -2653,7 +2752,7 @@ static int
add_res_sample_opt(struct hist_browser *browser __maybe_unused,
struct popup_action *act, char **optstr,
struct res_sample *res_sample,
- struct perf_evsel *evsel,
+ struct evsel *evsel,
enum rstype type)
{
if (!res_sample)
@@ -2814,7 +2913,7 @@ next:
}
}
-static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
+static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events,
const char *helpline,
bool left_exits,
struct hist_browser_timer *hbt,
@@ -2844,12 +2943,15 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
"For symbolic views (--sort has sym):\n\n" \
"ENTER Zoom into DSO/Threads & Annotate current symbol\n" \
"ESC Zoom out\n" \
+ "+ Expand/Collapse one callchain level\n" \
"a Annotate current symbol\n" \
"C Collapse all callchains\n" \
"d Zoom into current DSO\n" \
+ "e Expand/Collapse main entry callchains\n" \
"E Expand all callchains\n" \
"F Toggle percentage of filtered entries\n" \
"H Display column headers\n" \
+ "k Zoom into the kernel map\n" \
"L Change percent limit\n" \
"m Display context menu\n" \
"S Zoom into current Processor Socket\n" \
@@ -2894,16 +2996,19 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (symbol_conf.col_width_list_str)
perf_hpp__set_user_width(symbol_conf.col_width_list_str);
+ if (!is_report_browser(hbt))
+ browser->b.no_samples_msg = "Collecting samples...";
+
while (1) {
struct thread *thread = NULL;
struct map *map = NULL;
- int choice = 0;
+ int choice;
int socked_id = -1;
- nr_options = 0;
-
- key = hist_browser__run(browser, helpline,
- warn_lost_event);
+ key = 0; // reset key
+do_hotkey: // key came straight from options ui__popup_menu()
+ choice = nr_options = 0;
+ key = hist_browser__run(browser, helpline, warn_lost_event, key);
if (browser->he_selection != NULL) {
thread = hist_browser__selected_thread(browser);
@@ -2933,6 +3038,14 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
browser->selection->map->dso->annotate_warned)
continue;
+ if (symbol__annotation(browser->selection->sym)->src == NULL) {
+ ui_browser__warning(&browser->b, delay_secs * 2,
+ "No samples for the \"%s\" symbol.\n\n"
+ "Probably appeared just in a callchain",
+ browser->selection->sym->name);
+ continue;
+ }
+
actions->ms.map = browser->selection->map;
actions->ms.sym = browser->selection->sym;
do_annotate(browser, actions);
@@ -2944,6 +3057,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
actions->ms.map = map;
do_zoom_dso(browser, actions);
continue;
+ case 'k':
+ if (browser->selection != NULL)
+ hists_browser__zoom_map(browser, browser->selection->maps->machine->vmlinux_map);
+ continue;
case 'V':
verbose = (verbose + 1) % 4;
browser->show_dso = verbose > 0;
@@ -3045,6 +3162,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
continue;
}
+ actions->ms.map = map;
top = pstack__peek(browser->pstack);
if (top == &browser->hists->dso_filter) {
/*
@@ -3101,26 +3219,24 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
nr_options += add_annotate_opt(browser,
&actions[nr_options],
&options[nr_options],
- bi->from.map,
- bi->from.sym);
- if (bi->to.sym != bi->from.sym)
+ &bi->from.ms);
+ if (bi->to.ms.sym != bi->from.ms.sym)
nr_options += add_annotate_opt(browser,
&actions[nr_options],
&options[nr_options],
- bi->to.map,
- bi->to.sym);
+ &bi->to.ms);
} else {
nr_options += add_annotate_opt(browser,
&actions[nr_options],
&options[nr_options],
- browser->selection->map,
- browser->selection->sym);
+ browser->selection);
}
skip_annotation:
nr_options += add_thread_opt(browser, &actions[nr_options],
&options[nr_options], thread);
nr_options += add_dso_opt(browser, &actions[nr_options],
&options[nr_options], map);
+ nr_options += add_callchain_toggle_opt(browser, &actions[nr_options], &options[nr_options]);
nr_options += add_map_opt(browser, &actions[nr_options],
&options[nr_options],
browser->selection ?
@@ -3179,10 +3295,13 @@ skip_scripting:
do {
struct popup_action *act;
- choice = ui__popup_menu(nr_options, options);
- if (choice == -1 || choice >= nr_options)
+ choice = ui__popup_menu(nr_options, options, &key);
+ if (choice == -1)
break;
+ if (choice == nr_options)
+ goto do_hotkey;
+
act = &actions[choice];
key = act->fn(browser, act);
} while (key == 1);
@@ -3198,9 +3317,9 @@ out:
return key;
}
-struct perf_evsel_menu {
+struct evsel_menu {
struct ui_browser b;
- struct perf_evsel *selection;
+ struct evsel *selection;
struct annotation_options *annotation_opts;
bool lost_events, lost_events_warned;
float min_pcnt;
@@ -3210,9 +3329,9 @@ struct perf_evsel_menu {
static void perf_evsel_menu__write(struct ui_browser *browser,
void *entry, int row)
{
- struct perf_evsel_menu *menu = container_of(browser,
- struct perf_evsel_menu, b);
- struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
+ struct evsel_menu *menu = container_of(browser,
+ struct evsel_menu, b);
+ struct evsel *evsel = list_entry(entry, struct evsel, core.node);
struct hists *hists = evsel__hists(evsel);
bool current_entry = ui_browser__is_current_entry(browser, row);
unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
@@ -3225,7 +3344,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
HE_COLORSET_NORMAL);
if (perf_evsel__is_group_event(evsel)) {
- struct perf_evsel *pos;
+ struct evsel *pos;
ev_name = perf_evsel__group_name(evsel);
@@ -3257,13 +3376,13 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
menu->selection = evsel;
}
-static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
+static int perf_evsel_menu__run(struct evsel_menu *menu,
int nr_events, const char *help,
struct hist_browser_timer *hbt,
bool warn_lost_event)
{
- struct perf_evlist *evlist = menu->b.priv;
- struct perf_evsel *pos;
+ struct evlist *evlist = menu->b.priv;
+ struct evsel *pos;
const char *title = "Available samples";
int delay_secs = hbt ? hbt->refresh : 0;
int key;
@@ -3309,14 +3428,14 @@ browse_hists:
ui_browser__show_title(&menu->b, title);
switch (key) {
case K_TAB:
- if (pos->node.next == &evlist->entries)
- pos = perf_evlist__first(evlist);
+ if (pos->core.node.next == &evlist->core.entries)
+ pos = evlist__first(evlist);
else
pos = perf_evsel__next(pos);
goto browse_hists;
case K_UNTAB:
- if (pos->node.prev == &evlist->entries)
- pos = perf_evlist__last(evlist);
+ if (pos->core.node.prev == &evlist->core.entries)
+ pos = evlist__last(evlist);
else
pos = perf_evsel__prev(pos);
goto browse_hists;
@@ -3351,7 +3470,7 @@ out:
static bool filter_group_entries(struct ui_browser *browser __maybe_unused,
void *entry)
{
- struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
+ struct evsel *evsel = list_entry(entry, struct evsel, core.node);
if (symbol_conf.event_group && !perf_evsel__is_group_leader(evsel))
return true;
@@ -3359,7 +3478,7 @@ static bool filter_group_entries(struct ui_browser *browser __maybe_unused,
return false;
}
-static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
+static int __perf_evlist__tui_browse_hists(struct evlist *evlist,
int nr_entries, const char *help,
struct hist_browser_timer *hbt,
float min_pcnt,
@@ -3367,10 +3486,10 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
bool warn_lost_event,
struct annotation_options *annotation_opts)
{
- struct perf_evsel *pos;
- struct perf_evsel_menu menu = {
+ struct evsel *pos;
+ struct evsel_menu menu = {
.b = {
- .entries = &evlist->entries,
+ .entries = &evlist->core.entries,
.refresh = ui_browser__list_head_refresh,
.seek = ui_browser__list_head_seek,
.write = perf_evsel_menu__write,
@@ -3397,18 +3516,18 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
hbt, warn_lost_event);
}
-int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
+int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help,
struct hist_browser_timer *hbt,
float min_pcnt,
struct perf_env *env,
bool warn_lost_event,
struct annotation_options *annotation_opts)
{
- int nr_entries = evlist->nr_entries;
+ int nr_entries = evlist->core.nr_entries;
single_entry:
if (nr_entries == 1) {
- struct perf_evsel *first = perf_evlist__first(evlist);
+ struct evsel *first = evlist__first(evlist);
return perf_evsel__hists_browse(first, nr_entries, help,
false, hbt, min_pcnt,
@@ -3417,7 +3536,7 @@ single_entry:
}
if (symbol_conf.event_group) {
- struct perf_evsel *pos;
+ struct evsel *pos;
nr_entries = 0;
evlist__for_each_entry(evlist, pos) {
@@ -3434,3 +3553,75 @@ single_entry:
warn_lost_event,
annotation_opts);
}
+
+static int block_hists_browser__title(struct hist_browser *browser, char *bf,
+ size_t size)
+{
+ struct hists *hists = evsel__hists(browser->block_evsel);
+ const char *evname = perf_evsel__name(browser->block_evsel);
+ unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
+ int ret;
+
+ ret = scnprintf(bf, size, "# Samples: %lu", nr_samples);
+ if (evname)
+ scnprintf(bf + ret, size - ret, " of event '%s'", evname);
+
+ return 0;
+}
+
+int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,
+ float min_percent, struct perf_env *env,
+ struct annotation_options *annotation_opts)
+{
+ struct hists *hists = &bh->block_hists;
+ struct hist_browser *browser;
+ int key = -1;
+ struct popup_action action;
+ static const char help[] =
+ " q Quit \n";
+
+ browser = hist_browser__new(hists);
+ if (!browser)
+ return -1;
+
+ browser->block_evsel = evsel;
+ browser->title = block_hists_browser__title;
+ browser->min_pcnt = min_percent;
+ browser->env = env;
+ browser->annotation_opts = annotation_opts;
+
+ /* reset abort key so that it can get Ctrl-C as a key */
+ SLang_reset_tty();
+ SLang_init_tty(0, 0, 0);
+
+ memset(&action, 0, sizeof(action));
+
+ while (1) {
+ key = hist_browser__run(browser, "? - help", true, 0);
+
+ switch (key) {
+ case 'q':
+ goto out;
+ case '?':
+ ui_browser__help_window(&browser->b, help);
+ break;
+ case 'a':
+ case K_ENTER:
+ if (!browser->selection ||
+ !browser->selection->sym) {
+ continue;
+ }
+
+ action.ms.map = browser->selection->map;
+ action.ms.sym = browser->selection->sym;
+ do_annotate(browser, &action);
+ continue;
+ default:
+ break;
+ }
+ }
+
+out:
+ hist_browser__delete(browser);
+ return 0;
+}
diff --git a/tools/perf/ui/browsers/hists.h b/tools/perf/ui/browsers/hists.h
index 91d3e18b50aa..1e938d9ffa5e 100644
--- a/tools/perf/ui/browsers/hists.h
+++ b/tools/perf/ui/browsers/hists.h
@@ -5,6 +5,7 @@
#include "ui/browser.h"
struct annotation_options;
+struct evsel;
struct hist_browser {
struct ui_browser b;
@@ -15,6 +16,7 @@ struct hist_browser {
struct pstack *pstack;
struct perf_env *env;
struct annotation_options *annotation_opts;
+ struct evsel *block_evsel;
int print_seq;
bool show_dso;
bool show_headers;
@@ -32,7 +34,7 @@ struct hist_browser {
struct hist_browser *hist_browser__new(struct hists *hists);
void hist_browser__delete(struct hist_browser *browser);
int hist_browser__run(struct hist_browser *browser, const char *help,
- bool warn_lost_event);
+ bool warn_lost_event, int key);
void hist_browser__init(struct hist_browser *browser,
struct hists *hists);
#endif /* _PERF_UI_BROWSER_HISTS_H_ */
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index 4c545b92e20d..3d49b916c9e4 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -5,9 +5,9 @@
#include <stdlib.h>
#include <string.h>
#include <linux/bitops.h>
-#include "../../util/util.h"
#include "../../util/debug.h"
#include "../../util/map.h"
+#include "../../util/dso.h"
#include "../../util/symbol.h"
#include "../browser.h"
#include "../helpline.h"
diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c
index 8aa3547bb9ff..7cb2d6678039 100644
--- a/tools/perf/ui/browsers/res_sample.c
+++ b/tools/perf/ui/browsers/res_sample.c
@@ -6,6 +6,11 @@
#include "sort.h"
#include "config.h"
#include "time-utils.h"
+#include "../util.h"
+#include "../../util/util.h" // perf_exe()
+#include "../../perf.h"
+#include <stdlib.h>
+#include <string.h>
#include <linux/time64.h>
#include <linux/zalloc.h>
@@ -24,7 +29,7 @@ void res_sample_init(void)
}
int res_sample_browse(struct res_sample *res_samples, int num_res,
- struct perf_evsel *evsel, enum rstype rstype)
+ struct evsel *evsel, enum rstype rstype)
{
char **names;
int i, n;
@@ -51,7 +56,7 @@ int res_sample_browse(struct res_sample *res_samples, int num_res,
return -1;
}
}
- choice = ui__popup_menu(num_res, names);
+ choice = ui__popup_menu(num_res, names, NULL);
for (i = 0; i < num_res; i++)
zfree(&names[i]);
free(names);
@@ -66,7 +71,7 @@ int res_sample_browse(struct res_sample *res_samples, int num_res,
timestamp__scnprintf_nsec(r->time, tsample, sizeof tsample);
- attr_to_script(extra_format, &evsel->attr);
+ attr_to_script(extra_format, &evsel->core.attr);
if (asprintf(&cmd, "%s script %s%s --time %s %s%s %s%s --ns %s %s %s %s %s | less +/%s",
perf,
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index 4d565cc14076..47d2c7a8cbe1 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -1,12 +1,17 @@
// SPDX-License-Identifier: GPL-2.0
-#include "../../util/sort.h"
+#include "../../builtin.h"
+#include "../../perf.h"
+#include "../../util/util.h" // perf_exe()
+#include "../util.h"
#include "../../util/hist.h"
#include "../../util/debug.h"
#include "../../util/symbol.h"
#include "../browser.h"
#include "../libslang.h"
#include "config.h"
+#include <linux/string.h>
#include <linux/zalloc.h>
+#include <stdlib.h>
#define SCRIPT_NAMELEN 128
#define SCRIPT_MAX_NO 64
@@ -78,7 +83,7 @@ static int scripts_config(const char *var, const char *value, void *data)
* Return -1 on failure.
*/
static int list_scripts(char *script_name, bool *custom,
- struct perf_evsel *evsel)
+ struct evsel *evsel)
{
char *buf, *paths[SCRIPT_MAX_NO], *names[SCRIPT_MAX_NO];
int i, num, choice;
@@ -100,7 +105,7 @@ static int list_scripts(char *script_name, bool *custom,
return -1;
if (evsel)
- attr_to_script(scriptc.extra_format, &evsel->attr);
+ attr_to_script(scriptc.extra_format, &evsel->core.attr);
add_script_option("Show individual samples", "", &scriptc);
add_script_option("Show individual samples with assembler", "-F +insn --xed",
&scriptc);
@@ -121,7 +126,7 @@ static int list_scripts(char *script_name, bool *custom,
SCRIPT_FULLPATH_LEN);
if (num < 0)
num = 0;
- choice = ui__popup_menu(num + max_std, (char * const *)names);
+ choice = ui__popup_menu(num + max_std, (char * const *)names, NULL);
if (choice < 0) {
ret = -1;
goto out;
@@ -131,8 +136,10 @@ static int list_scripts(char *script_name, bool *custom,
int key = ui_browser__input_window("perf script command",
"Enter perf script command line (without perf script prefix)",
script_args, "", 0);
- if (key != K_ENTER)
- return -1;
+ if (key != K_ENTER) {
+ ret = -1;
+ goto out;
+ }
sprintf(script_name, "%s script %s", perf, script_args);
} else if (choice < num + max_std) {
strcpy(script_name, paths[choice]);
@@ -162,7 +169,7 @@ void run_script(char *cmd)
SLsmg_refresh();
}
-int script_browse(const char *script_opt, struct perf_evsel *evsel)
+int script_browse(const char *script_opt, struct evsel *evsel)
{
char *cmd, script_name[SCRIPT_FULLPATH_LEN];
bool custom = false;
diff --git a/tools/perf/ui/gtk/Build b/tools/perf/ui/gtk/Build
index ec22e899a224..eef708c502f4 100644
--- a/tools/perf/ui/gtk/Build
+++ b/tools/perf/ui/gtk/Build
@@ -1,4 +1,4 @@
-CFLAGS_gtk += -fPIC $(GTK_CFLAGS)
+CFLAGS_gtk += -fPIC $(GTK_CFLAGS) -Wno-deprecated-declarations
gtk-y += browser.o
gtk-y += hists.o
@@ -7,3 +7,8 @@ gtk-y += util.o
gtk-y += helpline.o
gtk-y += progress.o
gtk-y += annotate.o
+gtk-y += zalloc.o
+
+$(OUTPUT)ui/gtk/zalloc.o: ../lib/zalloc.c FORCE
+ $(call rule_mkdir)
+ $(call if_changed_dep,cc_o_c)
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index 3af87c18a914..22cc240f7371 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -5,6 +5,7 @@
#include "util/annotate.h"
#include "util/evsel.h"
#include "util/map.h"
+#include "util/dso.h"
#include "util/symbol.h"
#include "ui/helpline.h"
#include <inttypes.h>
@@ -53,10 +54,10 @@ static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym,
return ret;
}
-static int perf_gtk__get_offset(char *buf, size_t size, struct symbol *sym,
- struct map *map, struct disasm_line *dl)
+static int perf_gtk__get_offset(char *buf, size_t size, struct map_symbol *ms,
+ struct disasm_line *dl)
{
- u64 start = map__rip_2objdump(map, sym->start);
+ u64 start = map__rip_2objdump(ms->map, ms->sym->start);
strcpy(buf, "");
@@ -90,10 +91,11 @@ static int perf_gtk__get_line(char *buf, size_t size, struct disasm_line *dl)
return ret;
}
-static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
- struct map *map, struct perf_evsel *evsel,
+static int perf_gtk__annotate_symbol(GtkWidget *window, struct map_symbol *ms,
+ struct evsel *evsel,
struct hist_browser_timer *hbt __maybe_unused)
{
+ struct symbol *sym = ms->sym;
struct disasm_line *pos, *n;
struct annotation *notes;
GType col_types[MAX_ANN_COLS];
@@ -129,7 +131,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
gtk_list_store_append(store, &iter);
if (perf_evsel__is_group_event(evsel)) {
- for (i = 0; i < evsel->nr_members; i++) {
+ for (i = 0; i < evsel->core.nr_members; i++) {
ret += perf_gtk__get_percent(s + ret,
sizeof(s) - ret,
sym, pos,
@@ -143,7 +145,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
if (ret)
gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1);
- if (perf_gtk__get_offset(s, sizeof(s), sym, map, pos))
+ if (perf_gtk__get_offset(s, sizeof(s), ms, pos))
gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1);
if (perf_gtk__get_line(s, sizeof(s), pos))
gtk_list_store_set(store, &iter, ANN_COL__LINE, s, -1);
@@ -159,23 +161,23 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
return 0;
}
-static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
- struct perf_evsel *evsel,
+static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel,
struct hist_browser_timer *hbt)
{
+ struct symbol *sym = ms->sym;
GtkWidget *window;
GtkWidget *notebook;
GtkWidget *scrolled_window;
GtkWidget *tab_label;
int err;
- if (map->dso->annotate_warned)
+ if (ms->map->dso->annotate_warned)
return -1;
- err = symbol__annotate(sym, map, evsel, 0, &annotation__default_options, NULL);
+ err = symbol__annotate(ms, evsel, 0, &annotation__default_options, NULL);
if (err) {
char msg[BUFSIZ];
- symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
+ symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
ui__error("Couldn't annotate %s: %s\n", sym->name, msg);
return -1;
}
@@ -233,15 +235,15 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window,
tab_label);
- perf_gtk__annotate_symbol(scrolled_window, sym, map, evsel, hbt);
+ perf_gtk__annotate_symbol(scrolled_window, ms, evsel, hbt);
return 0;
}
int hist_entry__gtk_annotate(struct hist_entry *he,
- struct perf_evsel *evsel,
+ struct evsel *evsel,
struct hist_browser_timer *hbt)
{
- return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
+ return symbol__gtk_annotate(&he->ms, evsel, hbt);
}
void perf_gtk__show_annotations(void)
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 4820e25ac68d..8f3e43d148a8 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -1,6 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-#include "../evlist.h"
-#include "../cache.h"
#include "../evsel.h"
#include "../sort.h"
#include "../hist.h"
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 9846ea5c831b..a9563932fa04 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -52,16 +52,16 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void)
}
#endif
-struct perf_evsel;
-struct perf_evlist;
+struct evsel;
+struct evlist;
struct hist_entry;
struct hist_browser_timer;
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
+int perf_evlist__gtk_browse_hists(struct evlist *evlist, const char *help,
struct hist_browser_timer *hbt,
float min_pcnt);
int hist_entry__gtk_annotate(struct hist_entry *he,
- struct perf_evsel *evsel,
+ struct evsel *evsel,
struct hist_browser_timer *hbt);
void perf_gtk__show_annotations(void);
diff --git a/tools/perf/ui/gtk/helpline.c b/tools/perf/ui/gtk/helpline.c
index fbf1ea9ce9a2..e40a006aead8 100644
--- a/tools/perf/ui/gtk/helpline.c
+++ b/tools/perf/ui/gtk/helpline.c
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <string.h>
+#include <linux/kernel.h>
#include "gtk.h"
#include "../ui.h"
#include "../helpline.h"
-#include "../../util/debug.h"
static void gtk_helpline_pop(void)
{
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 3955ed1d1bd9..ed1a97b2c4b0 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include "../evlist.h"
-#include "../cache.h"
#include "../callchain.h"
#include "../evsel.h"
#include "../sort.h"
@@ -9,6 +8,7 @@
#include "../string2.h"
#include "gtk.h"
#include <signal.h>
+#include <stdlib.h>
#include <linux/string.h>
#define MAX_COLUMNS 32
@@ -590,12 +590,12 @@ static void perf_gtk__show_hierarchy(GtkWidget *window, struct hists *hists,
gtk_container_add(GTK_CONTAINER(window), view);
}
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
+int perf_evlist__gtk_browse_hists(struct evlist *evlist,
const char *help,
struct hist_browser_timer *hbt __maybe_unused,
float min_pcnt)
{
- struct perf_evsel *pos;
+ struct evsel *pos;
GtkWidget *vbox;
GtkWidget *notebook;
GtkWidget *info_bar;
@@ -645,7 +645,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
if (!perf_evsel__is_group_leader(pos))
continue;
- if (pos->nr_members > 1) {
+ if (pos->core.nr_members > 1) {
perf_evsel__group_desc(pos, buf, size);
evname = buf;
}
diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c
index b6ad8857da78..eea6fcde518a 100644
--- a/tools/perf/ui/gtk/progress.c
+++ b/tools/perf/ui/gtk/progress.c
@@ -3,7 +3,6 @@
#include "gtk.h"
#include "../progress.h"
-#include "util.h"
static GtkWidget *dialog;
static GtkWidget *progress;
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c
index 506e73b3834c..f5eee4d66873 100644
--- a/tools/perf/ui/gtk/setup.c
+++ b/tools/perf/ui/gtk/setup.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include "gtk.h"
-#include "../../util/cache.h"
-#include "../../util/debug.h"
+#include <linux/compiler.h>
+#include "../util.h"
extern struct perf_error_ops perf_gtk_eops;
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index c28bdb7517ac..c47f5c387838 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include "../util.h"
-#include "../../util/debug.h"
#include "gtk.h"
+#include <stdlib.h>
#include <string.h>
#include <linux/zalloc.h>
diff --git a/tools/perf/ui/helpline.c b/tools/perf/ui/helpline.c
index b3c421429ed4..911182b3f5e6 100644
--- a/tools/perf/ui/helpline.c
+++ b/tools/perf/ui/helpline.c
@@ -3,10 +3,8 @@
#include <stdlib.h>
#include <string.h>
-#include "../debug.h"
#include "helpline.h"
#include "ui.h"
-#include "../util.h"
char ui_helpline__current[512];
diff --git a/tools/perf/ui/helpline.h b/tools/perf/ui/helpline.h
index 8f775a053ca3..2165a098dee8 100644
--- a/tools/perf/ui/helpline.h
+++ b/tools/perf/ui/helpline.h
@@ -5,8 +5,6 @@
#include <stdio.h>
#include <stdarg.h>
-#include "../util/cache.h"
-
struct ui_helpline {
void (*pop)(void);
void (*push)(const char *msg);
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 412d6f1626e3..f73675500061 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -1,14 +1,17 @@
// SPDX-License-Identifier: GPL-2.0
#include <inttypes.h>
#include <math.h>
+#include <stdlib.h>
+#include <string.h>
#include <linux/compiler.h>
#include "../util/callchain.h"
+#include "../util/debug.h"
#include "../util/hist.h"
-#include "../util/util.h"
#include "../util/sort.h"
#include "../util/evsel.h"
#include "../util/evlist.h"
+#include "../perf.h"
/* hist period print (hpp) functions */
@@ -25,7 +28,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
{
int ret;
struct hists *hists = he->hists;
- struct perf_evsel *evsel = hists_to_evsel(hists);
+ struct evsel *evsel = hists_to_evsel(hists);
char *buf = hpp->buf;
size_t size = hpp->size;
@@ -43,7 +46,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
if (perf_evsel__is_group_event(evsel)) {
int prev_idx, idx_delta;
struct hist_entry *pair;
- int nr_members = evsel->nr_members;
+ int nr_members = evsel->core.nr_members;
prev_idx = perf_evsel__group_idx(evsel);
@@ -153,7 +156,7 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b,
{
s64 ret;
int i, nr_members;
- struct perf_evsel *evsel;
+ struct evsel *evsel;
struct hist_entry *pair;
u64 *fields_a, *fields_b;
@@ -165,7 +168,7 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b,
if (!perf_evsel__is_group_event(evsel))
return ret;
- nr_members = evsel->nr_members;
+ nr_members = evsel->core.nr_members;
fields_a = calloc(nr_members, sizeof(*fields_a));
fields_b = calloc(nr_members, sizeof(*fields_b));
@@ -223,10 +226,10 @@ static int hpp__width_fn(struct perf_hpp_fmt *fmt,
struct hists *hists)
{
int len = fmt->user_len ?: fmt->len;
- struct perf_evsel *evsel = hists_to_evsel(hists);
+ struct evsel *evsel = hists_to_evsel(hists);
if (symbol_conf.event_group)
- len = max(len, evsel->nr_members * fmt->len);
+ len = max(len, evsel->core.nr_members * fmt->len);
if (len < (int)strlen(fmt->name))
len = strlen(fmt->name);
@@ -795,9 +798,9 @@ static int add_hierarchy_fmt(struct hists *hists, struct perf_hpp_fmt *fmt)
}
int perf_hpp__setup_hists_formats(struct perf_hpp_list *list,
- struct perf_evlist *evlist)
+ struct evlist *evlist)
{
- struct perf_evsel *evsel;
+ struct evsel *evsel;
struct perf_hpp_fmt *fmt;
struct hists *hists;
int ret;
diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c
index 8cd3b64c6893..99d60223c74b 100644
--- a/tools/perf/ui/progress.c
+++ b/tools/perf/ui/progress.c
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
-#include "../util/cache.h"
#include "progress.h"
static void null_progress__update(struct ui_progress *p __maybe_unused)
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index 44fe824e96cd..700335cde618 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include <pthread.h>
#include <dlfcn.h>
+#include <unistd.h>
-#include "../util/cache.h"
+#include <subcmd/pager.h>
#include "../util/debug.h"
#include "../util/hist.h"
-#include "../util/util.h"
+#include "ui.h"
pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
void *perf_gtk_handle;
@@ -89,9 +90,9 @@ void setup_browser(bool fallback_to_pager)
printf("GTK browser requested but could not find %s\n",
PERF_GTK_DSO);
sleep(1);
+ use_browser = 1;
/* fall through */
case 1:
- use_browser = 1;
if (ui__init() == 0)
break;
/* fall through */
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index ee7ea6deed21..2ab2af4d4849 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -1,17 +1,21 @@
// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
+#include <stdlib.h>
#include <linux/string.h>
#include "../../util/callchain.h"
+#include "../../util/debug.h"
+#include "../../util/event.h"
#include "../../util/hist.h"
#include "../../util/map.h"
-#include "../../util/map_groups.h"
+#include "../../util/maps.h"
#include "../../util/symbol.h"
#include "../../util/sort.h"
#include "../../util/evsel.h"
#include "../../util/srcline.h"
#include "../../util/string2.h"
#include "../../util/thread.h"
+#include "../../util/block-info.h"
#include <linux/ctype.h>
#include <linux/zalloc.h>
@@ -555,6 +559,25 @@ static int hist_entry__block_fprintf(struct hist_entry *he,
return ret;
}
+static int hist_entry__individual_block_fprintf(struct hist_entry *he,
+ char *bf, size_t size,
+ FILE *fp)
+{
+ int ret = 0;
+
+ struct perf_hpp hpp = {
+ .buf = bf,
+ .size = size,
+ .skip = false,
+ };
+
+ hist_entry__snprintf(he, &hpp);
+ if (!hpp.skip)
+ ret += fprintf(fp, "%s\n", bf);
+
+ return ret;
+}
+
static int hist_entry__fprintf(struct hist_entry *he, size_t size,
char *bf, size_t bfsz, FILE *fp,
bool ignore_callchains)
@@ -577,6 +600,9 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
if (symbol_conf.report_block)
return hist_entry__block_fprintf(he, bf, size, fp);
+ if (symbol_conf.report_individual_block)
+ return hist_entry__individual_block_fprintf(he, bf, size, fp);
+
hist_entry__snprintf(he, &hpp);
ret = fprintf(fp, "%s\n", bf);
@@ -831,7 +857,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
if (h->filtered)
continue;
- percent = hist_entry__get_percent_limit(h);
+ if (symbol_conf.report_individual_block)
+ percent = block_info__total_cycles_percent(h);
+ else
+ percent = hist_entry__get_percent_limit(h);
+
if (percent < min_pcnt)
continue;
@@ -855,7 +885,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
}
if (h->ms.map == NULL && verbose > 1) {
- map_groups__fprintf(h->thread->mg, fp);
+ maps__fprintf(h->thread->maps, fp);
fprintf(fp, "%.10s end\n", graph_dotted_line);
}
}
diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c
index 93d6b7240285..298d6af82fdd 100644
--- a/tools/perf/ui/tui/helpline.c
+++ b/tools/perf/ui/tui/helpline.c
@@ -3,8 +3,9 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
-#include "../../util/debug.h"
#include "../helpline.h"
#include "../ui.h"
#include "../libslang.h"
diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c
index 5a24dd3ce4db..3d74af5a7ece 100644
--- a/tools/perf/ui/tui/progress.c
+++ b/tools/perf/ui/tui/progress.c
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
-#include "../../util/cache.h"
#include "../progress.h"
#include "../libslang.h"
#include "../ui.h"
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index 3ad0d3363ac6..e9bfe856a5de 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -1,16 +1,15 @@
-// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <unistd.h>
#include <linux/kernel.h>
#ifdef HAVE_BACKTRACE_SUPPORT
#include <execinfo.h>
#endif
-#include "../../util/cache.h"
#include "../../util/debug.h"
-#include "../../util/util.h"
+#include "../../perf.h"
#include "../browser.h"
#include "../helpline.h"
#include "../ui.h"
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
index fe5e571816fc..0f562e2cb1e8 100644
--- a/tools/perf/ui/tui/util.c
+++ b/tools/perf/ui/tui/util.c
@@ -5,8 +5,6 @@
#include <stdlib.h>
#include <sys/ttydefaults.h>
-#include "../../util/cache.h"
-#include "../../util/debug.h"
#include "../browser.h"
#include "../keysyms.h"
#include "../helpline.h"
@@ -25,7 +23,7 @@ static void ui_browser__argv_write(struct ui_browser *browser,
ui_browser__write_nstring(browser, *arg, browser->width);
}
-static int popup_menu__run(struct ui_browser *menu)
+static int popup_menu__run(struct ui_browser *menu, int *keyp)
{
int key;
@@ -47,6 +45,11 @@ static int popup_menu__run(struct ui_browser *menu)
key = -1;
break;
default:
+ if (keyp) {
+ *keyp = key;
+ key = menu->nr_entries;
+ break;
+ }
continue;
}
@@ -57,7 +60,7 @@ static int popup_menu__run(struct ui_browser *menu)
return key;
}
-int ui__popup_menu(int argc, char * const argv[])
+int ui__popup_menu(int argc, char * const argv[], int *keyp)
{
struct ui_browser menu = {
.entries = (void *)argv,
@@ -66,8 +69,7 @@ int ui__popup_menu(int argc, char * const argv[])
.write = ui_browser__argv_write,
.nr_entries = argc,
};
-
- return popup_menu__run(&menu);
+ return popup_menu__run(&menu, keyp);
}
int ui_browser__input_window(const char *title, const char *text, char *input,
@@ -162,8 +164,7 @@ next_key:
return key;
}
-int ui__question_window(const char *title, const char *text,
- const char *exit_msg, int delay_secs)
+void __ui__info_window(const char *title, const char *text, const char *exit_msg)
{
int x, y;
int max_len = 0, nr_lines = 0;
@@ -185,10 +186,10 @@ int ui__question_window(const char *title, const char *text,
t = sep + 1;
}
- pthread_mutex_lock(&ui__lock);
-
max_len += 2;
- nr_lines += 4;
+ nr_lines += 2;
+ if (exit_msg)
+ nr_lines += 2;
y = SLtt_Screen_Rows / 2 - nr_lines / 2,
x = SLtt_Screen_Cols / 2 - max_len / 2;
@@ -199,18 +200,34 @@ int ui__question_window(const char *title, const char *text,
SLsmg_write_string((char *)title);
}
SLsmg_gotorc(++y, x);
- nr_lines -= 2;
+ if (exit_msg)
+ nr_lines -= 2;
max_len -= 2;
SLsmg_write_wrapped_string((unsigned char *)text, y, x,
nr_lines, max_len, 1);
- SLsmg_gotorc(y + nr_lines - 2, x);
- SLsmg_write_nstring((char *)" ", max_len);
- SLsmg_gotorc(y + nr_lines - 1, x);
- SLsmg_write_nstring((char *)exit_msg, max_len);
- SLsmg_refresh();
+ if (exit_msg) {
+ SLsmg_gotorc(y + nr_lines - 2, x);
+ SLsmg_write_nstring((char *)" ", max_len);
+ SLsmg_gotorc(y + nr_lines - 1, x);
+ SLsmg_write_nstring((char *)exit_msg, max_len);
+ }
+}
+void ui__info_window(const char *title, const char *text)
+{
+ pthread_mutex_lock(&ui__lock);
+ __ui__info_window(title, text, NULL);
+ SLsmg_refresh();
pthread_mutex_unlock(&ui__lock);
+}
+int ui__question_window(const char *title, const char *text,
+ const char *exit_msg, int delay_secs)
+{
+ pthread_mutex_lock(&ui__lock);
+ __ui__info_window(title, text, exit_msg);
+ SLsmg_refresh();
+ pthread_mutex_unlock(&ui__lock);
return ui__getch(delay_secs);
}
diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c
index 63bf06e80ab9..689b27c34246 100644
--- a/tools/perf/ui/util.c
+++ b/tools/perf/ui/util.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include "util.h"
-#include "../debug.h"
-
+#include "../util/debug.h"
+#include <stdio.h>
/*
* Default error logging functions
diff --git a/tools/perf/ui/util.h b/tools/perf/ui/util.h
index 5e44223b56fa..e30cea807564 100644
--- a/tools/perf/ui/util.h
+++ b/tools/perf/ui/util.h
@@ -5,9 +5,11 @@
#include <stdarg.h>
int ui__getch(int delay_secs);
-int ui__popup_menu(int argc, char * const argv[]);
+int ui__popup_menu(int argc, char * const argv[], int *keyp);
int ui__help_window(const char *text);
int ui__dialog_yesno(const char *msg);
+void __ui__info_window(const char *title, const char *text, const char *exit_msg);
+void ui__info_window(const char *title, const char *text);
int ui__question_window(const char *title, const char *text,
const char *exit_msg, int delay_secs);
OpenPOWER on IntegriCloud