mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-24 09:50:04 +00:00
perf hist: Adopt filter by dso and by thread methods from the newt browser
Those are really not specific to the newt code, can be used by other UI frontends. Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
e3174cfd2a
commit
b09e0190ac
5 changed files with 89 additions and 85 deletions
|
@ -301,10 +301,7 @@ static int __cmd_report(void)
|
||||||
hists__collapse_resort(hists);
|
hists__collapse_resort(hists);
|
||||||
hists__output_resort(hists);
|
hists__output_resort(hists);
|
||||||
if (use_browser)
|
if (use_browser)
|
||||||
perf_session__browse_hists(&hists->entries,
|
hists__browse(hists, help, input_name);
|
||||||
hists->nr_entries,
|
|
||||||
hists->stats.total, help,
|
|
||||||
input_name);
|
|
||||||
else {
|
else {
|
||||||
if (rb_first(&session->hists.entries) ==
|
if (rb_first(&session->hists.entries) ==
|
||||||
rb_last(&session->hists.entries))
|
rb_last(&session->hists.entries))
|
||||||
|
|
|
@ -784,3 +784,62 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum hist_filter {
|
||||||
|
HIST_FILTER__DSO,
|
||||||
|
HIST_FILTER__THREAD,
|
||||||
|
};
|
||||||
|
|
||||||
|
void hists__filter_by_dso(struct hists *self, const struct dso *dso)
|
||||||
|
{
|
||||||
|
struct rb_node *nd;
|
||||||
|
|
||||||
|
self->nr_entries = self->stats.total = 0;
|
||||||
|
self->max_sym_namelen = 0;
|
||||||
|
|
||||||
|
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
|
||||||
|
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
|
|
||||||
|
if (symbol_conf.exclude_other && !h->parent)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) {
|
||||||
|
h->filtered |= (1 << HIST_FILTER__DSO);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
h->filtered &= ~(1 << HIST_FILTER__DSO);
|
||||||
|
if (!h->filtered) {
|
||||||
|
++self->nr_entries;
|
||||||
|
self->stats.total += h->count;
|
||||||
|
if (h->ms.sym &&
|
||||||
|
self->max_sym_namelen < h->ms.sym->namelen)
|
||||||
|
self->max_sym_namelen = h->ms.sym->namelen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hists__filter_by_thread(struct hists *self, const struct thread *thread)
|
||||||
|
{
|
||||||
|
struct rb_node *nd;
|
||||||
|
|
||||||
|
self->nr_entries = self->stats.total = 0;
|
||||||
|
self->max_sym_namelen = 0;
|
||||||
|
|
||||||
|
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
|
||||||
|
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
|
|
||||||
|
if (thread != NULL && h->thread != thread) {
|
||||||
|
h->filtered |= (1 << HIST_FILTER__THREAD);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
h->filtered &= ~(1 << HIST_FILTER__THREAD);
|
||||||
|
if (!h->filtered) {
|
||||||
|
++self->nr_entries;
|
||||||
|
self->stats.total += h->count;
|
||||||
|
if (h->ms.sym &&
|
||||||
|
self->max_sym_namelen < h->ms.sym->namelen)
|
||||||
|
self->max_sym_namelen = h->ms.sym->namelen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -44,4 +44,19 @@ void hists__output_resort(struct hists *self);
|
||||||
void hists__collapse_resort(struct hists *self);
|
void hists__collapse_resort(struct hists *self);
|
||||||
size_t hists__fprintf(struct hists *self, struct hists *pair,
|
size_t hists__fprintf(struct hists *self, struct hists *pair,
|
||||||
bool show_displacement, FILE *fp);
|
bool show_displacement, FILE *fp);
|
||||||
|
|
||||||
|
void hists__filter_by_dso(struct hists *self, const struct dso *dso);
|
||||||
|
void hists__filter_by_thread(struct hists *self, const struct thread *thread);
|
||||||
|
|
||||||
|
#ifdef NO_NEWT_SUPPORT
|
||||||
|
static inline int hists__browse(struct hists self __used,
|
||||||
|
const char *helpline __used,
|
||||||
|
const char *input_name __used)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int hists__browse(struct hists *self, const char *helpline,
|
||||||
|
const char *input_name);
|
||||||
|
#endif
|
||||||
#endif /* __PERF_HIST_H */
|
#endif /* __PERF_HIST_H */
|
||||||
|
|
|
@ -410,8 +410,8 @@ static void hist_browser__delete(struct hist_browser *self)
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hist_browser__populate(struct hist_browser *self, struct rb_root *hists,
|
static int hist_browser__populate(struct hist_browser *self, struct hists *hists,
|
||||||
u64 nr_hists, u64 session_total, const char *title)
|
const char *title)
|
||||||
{
|
{
|
||||||
int max_len = 0, idx, cols, rows;
|
int max_len = 0, idx, cols, rows;
|
||||||
struct ui_progress *progress;
|
struct ui_progress *progress;
|
||||||
|
@ -426,7 +426,7 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(str, sizeof(str), "Samples: %Ld ",
|
snprintf(str, sizeof(str), "Samples: %Ld ",
|
||||||
session_total);
|
hists->stats.total);
|
||||||
newtDrawRootText(0, 0, str);
|
newtDrawRootText(0, 0, str);
|
||||||
|
|
||||||
newtGetScreenSize(NULL, &rows);
|
newtGetScreenSize(NULL, &rows);
|
||||||
|
@ -442,24 +442,25 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
|
||||||
newtComponentAddCallback(self->tree, hist_browser__selection,
|
newtComponentAddCallback(self->tree, hist_browser__selection,
|
||||||
&self->selection);
|
&self->selection);
|
||||||
|
|
||||||
progress = ui_progress__new("Adding entries to the browser...", nr_hists);
|
progress = ui_progress__new("Adding entries to the browser...",
|
||||||
|
hists->nr_entries);
|
||||||
if (progress == NULL)
|
if (progress == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
|
for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
|
||||||
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (h->filtered)
|
if (h->filtered)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
len = hist_entry__append_browser(h, self->tree, session_total);
|
len = hist_entry__append_browser(h, self->tree, hists->stats.total);
|
||||||
if (len > max_len)
|
if (len > max_len)
|
||||||
max_len = len;
|
max_len = len;
|
||||||
if (symbol_conf.use_callchain)
|
if (symbol_conf.use_callchain)
|
||||||
hist_entry__append_callchain_browser(h, self->tree,
|
hist_entry__append_callchain_browser(h, self->tree,
|
||||||
session_total, idx++);
|
hists->stats.total, idx++);
|
||||||
++curr_hist;
|
++curr_hist;
|
||||||
if (curr_hist % 5)
|
if (curr_hist % 5)
|
||||||
ui_progress__update(progress, curr_hist);
|
ui_progress__update(progress, curr_hist);
|
||||||
|
@ -490,57 +491,6 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum hist_filter {
|
|
||||||
HIST_FILTER__DSO,
|
|
||||||
HIST_FILTER__THREAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
static u64 hists__filter_by_dso(struct rb_root *hists, const struct dso *dso,
|
|
||||||
u64 *session_total)
|
|
||||||
{
|
|
||||||
struct rb_node *nd;
|
|
||||||
u64 nr_hists = 0;
|
|
||||||
|
|
||||||
*session_total = 0;
|
|
||||||
|
|
||||||
for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
|
|
||||||
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
|
||||||
|
|
||||||
if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) {
|
|
||||||
h->filtered |= (1 << HIST_FILTER__DSO);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
h->filtered &= ~(1 << HIST_FILTER__DSO);
|
|
||||||
++nr_hists;
|
|
||||||
*session_total += h->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nr_hists;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 hists__filter_by_thread(struct rb_root *hists, const struct thread *thread,
|
|
||||||
u64 *session_total)
|
|
||||||
{
|
|
||||||
struct rb_node *nd;
|
|
||||||
u64 nr_hists = 0;
|
|
||||||
|
|
||||||
*session_total = 0;
|
|
||||||
|
|
||||||
for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
|
|
||||||
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
|
||||||
|
|
||||||
if (thread != NULL && h->thread != thread) {
|
|
||||||
h->filtered |= (1 << HIST_FILTER__THREAD);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
h->filtered &= ~(1 << HIST_FILTER__THREAD);
|
|
||||||
++nr_hists;
|
|
||||||
*session_total += h->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nr_hists;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct thread *hist_browser__selected_thread(struct hist_browser *self)
|
static struct thread *hist_browser__selected_thread(struct hist_browser *self)
|
||||||
{
|
{
|
||||||
int *indexes;
|
int *indexes;
|
||||||
|
@ -577,9 +527,7 @@ static int hist_browser__title(char *bf, size_t size, const char *input_name,
|
||||||
return printed ?: snprintf(bf, size, "Report: %s", input_name);
|
return printed ?: snprintf(bf, size, "Report: %s", input_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
|
int hists__browse(struct hists *self, const char *helpline, const char *input_name)
|
||||||
u64 session_total, const char *helpline,
|
|
||||||
const char *input_name)
|
|
||||||
{
|
{
|
||||||
struct hist_browser *browser = hist_browser__new();
|
struct hist_browser *browser = hist_browser__new();
|
||||||
const struct thread *thread_filter = NULL;
|
const struct thread *thread_filter = NULL;
|
||||||
|
@ -595,7 +543,7 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
|
||||||
|
|
||||||
hist_browser__title(msg, sizeof(msg), input_name,
|
hist_browser__title(msg, sizeof(msg), input_name,
|
||||||
dso_filter, thread_filter);
|
dso_filter, thread_filter);
|
||||||
if (hist_browser__populate(browser, hists, nr_hists, session_total, msg) < 0)
|
if (hist_browser__populate(browser, self, msg) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -672,10 +620,10 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
|
||||||
newtPushHelpLine(msg);
|
newtPushHelpLine(msg);
|
||||||
dso_filter = dso;
|
dso_filter = dso;
|
||||||
}
|
}
|
||||||
nr_hists = hists__filter_by_dso(hists, dso_filter, &session_total);
|
hists__filter_by_dso(self, dso_filter);
|
||||||
hist_browser__title(msg, sizeof(msg), input_name,
|
hist_browser__title(msg, sizeof(msg), input_name,
|
||||||
dso_filter, thread_filter);
|
dso_filter, thread_filter);
|
||||||
if (hist_browser__populate(browser, hists, nr_hists, session_total, msg) < 0)
|
if (hist_browser__populate(browser, self, msg) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
} else if (choice == zoom_thread) {
|
} else if (choice == zoom_thread) {
|
||||||
if (thread_filter) {
|
if (thread_filter) {
|
||||||
|
@ -689,10 +637,10 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
|
||||||
newtPushHelpLine(msg);
|
newtPushHelpLine(msg);
|
||||||
thread_filter = thread;
|
thread_filter = thread;
|
||||||
}
|
}
|
||||||
nr_hists = hists__filter_by_thread(hists, thread_filter, &session_total);
|
hists__filter_by_thread(self, thread_filter);
|
||||||
hist_browser__title(msg, sizeof(msg), input_name,
|
hist_browser__title(msg, sizeof(msg), input_name,
|
||||||
dso_filter, thread_filter);
|
dso_filter, thread_filter);
|
||||||
if (hist_browser__populate(browser, hists, nr_hists, session_total, msg) < 0)
|
if (hist_browser__populate(browser, self, msg) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,21 +102,6 @@ int perf_session__create_kernel_maps(struct perf_session *self);
|
||||||
int do_read(int fd, void *buf, size_t size);
|
int do_read(int fd, void *buf, size_t size);
|
||||||
void perf_session__update_sample_type(struct perf_session *self);
|
void perf_session__update_sample_type(struct perf_session *self);
|
||||||
|
|
||||||
#ifdef NO_NEWT_SUPPORT
|
|
||||||
static inline int perf_session__browse_hists(struct rb_root *hists __used,
|
|
||||||
u64 nr_hists __used,
|
|
||||||
u64 session_total __used,
|
|
||||||
const char *helpline __used,
|
|
||||||
const char *input_name __used)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
|
|
||||||
u64 session_total, const char *helpline,
|
|
||||||
const char *input_name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
struct machine *perf_session__find_host_machine(struct perf_session *self)
|
struct machine *perf_session__find_host_machine(struct perf_session *self)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue