Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b09e0190 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e3174cfd
Loading
Loading
Loading
Loading
+1 −4
Original line number Original line Diff line number Diff line
@@ -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))
+59 −0
Original line number Original line Diff line number Diff line
@@ -784,3 +784,62 @@ print_entries:


	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;
		}
	}
}
+15 −0
Original line number Original line Diff line number Diff line
@@ -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 */
+14 −66
Original line number Original line Diff line number Diff line
@@ -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 @@ do_annotate:
				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 @@ do_annotate:
				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;
		}
		}
	}
	}
+0 −15
Original line number Original line Diff line number Diff line
@@ -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)
{
{