diff options
| author | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-14 12:21:53 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-08-15 16:10:19 +0200 | 
| commit | 6baa0a5ae0954fb2486c480a20556a9f1aee0965 (patch) | |
| tree | b85e485562b34b222153d41414dec655724e26b8 /tools/perf/builtin-annotate.c | |
| parent | be750231ce1599b86fbba213e3da8344ece262e2 (diff) | |
| download | olio-linux-3.10-6baa0a5ae0954fb2486c480a20556a9f1aee0965.tar.xz olio-linux-3.10-6baa0a5ae0954fb2486c480a20556a9f1aee0965.zip  | |
perf tools: Factorize the thread code in a dedicated file
Factorize the thread management code used by perf-annotate and
perf-report in dedicated source and header files.
v2: pass last_match by address so that it can actually be
modified.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <1250245313-6995-1-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 173 | 
1 files changed, 18 insertions, 155 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 543c4524f8c..3bedaa5d21d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -20,6 +20,7 @@  #include "util/parse-options.h"  #include "util/parse-events.h" +#include "util/thread.h"  #define SHOW_KERNEL	1  #define SHOW_USER	2 @@ -44,6 +45,9 @@ static int		print_line;  static unsigned long	page_size;  static unsigned long	mmap_window = 32; +static struct rb_root	threads; +static struct thread	*last_match; +  struct sym_ext {  	struct rb_node	node; @@ -51,154 +55,6 @@ struct sym_ext {  	char		*path;  }; - -struct thread { -	struct rb_node	 rb_node; -	struct list_head maps; -	pid_t		 pid; -	char		 *comm; -}; - -static struct thread *thread__new(pid_t pid) -{ -	struct thread *self = malloc(sizeof(*self)); - -	if (self != NULL) { -		self->pid = pid; -		self->comm = malloc(32); -		if (self->comm) -			snprintf(self->comm, 32, ":%d", self->pid); -		INIT_LIST_HEAD(&self->maps); -	} - -	return self; -} - -static int thread__set_comm(struct thread *self, const char *comm) -{ -	if (self->comm) -		free(self->comm); -	self->comm = strdup(comm); -	return self->comm ? 0 : -ENOMEM; -} - -static size_t thread__fprintf(struct thread *self, FILE *fp) -{ -	struct map *pos; -	size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm); - -	list_for_each_entry(pos, &self->maps, node) -		ret += map__fprintf(pos, fp); - -	return ret; -} - - -static struct rb_root threads; -static struct thread *last_match; - -static struct thread *threads__findnew(pid_t pid) -{ -	struct rb_node **p = &threads.rb_node; -	struct rb_node *parent = NULL; -	struct thread *th; - -	/* -	 * Font-end cache - PID lookups come in blocks, -	 * so most of the time we dont have to look up -	 * the full rbtree: -	 */ -	if (last_match && last_match->pid == pid) -		return last_match; - -	while (*p != NULL) { -		parent = *p; -		th = rb_entry(parent, struct thread, rb_node); - -		if (th->pid == pid) { -			last_match = th; -			return th; -		} - -		if (pid < th->pid) -			p = &(*p)->rb_left; -		else -			p = &(*p)->rb_right; -	} - -	th = thread__new(pid); -	if (th != NULL) { -		rb_link_node(&th->rb_node, parent, p); -		rb_insert_color(&th->rb_node, &threads); -		last_match = th; -	} - -	return th; -} - -static void thread__insert_map(struct thread *self, struct map *map) -{ -	struct map *pos, *tmp; - -	list_for_each_entry_safe(pos, tmp, &self->maps, node) { -		if (map__overlap(pos, map)) { -			list_del_init(&pos->node); -			/* XXX leaks dsos */ -			free(pos); -		} -	} - -	list_add_tail(&map->node, &self->maps); -} - -static int thread__fork(struct thread *self, struct thread *parent) -{ -	struct map *map; - -	if (self->comm) -		free(self->comm); -	self->comm = strdup(parent->comm); -	if (!self->comm) -		return -ENOMEM; - -	list_for_each_entry(map, &parent->maps, node) { -		struct map *new = map__clone(map); -		if (!new) -			return -ENOMEM; -		thread__insert_map(self, new); -	} - -	return 0; -} - -static struct map *thread__find_map(struct thread *self, u64 ip) -{ -	struct map *pos; - -	if (self == NULL) -		return NULL; - -	list_for_each_entry(pos, &self->maps, node) -		if (ip >= pos->start && ip <= pos->end) -			return pos; - -	return NULL; -} - -static size_t threads__fprintf(FILE *fp) -{ -	size_t ret = 0; -	struct rb_node *nd; - -	for (nd = rb_first(&threads); nd; nd = rb_next(nd)) { -		struct thread *pos = rb_entry(nd, struct thread, rb_node); - -		ret += thread__fprintf(pos, fp); -	} - -	return ret; -} -  /*   * histogram, sorted on item, collects counts   */ @@ -624,7 +480,7 @@ static void output__resort(void)  static void register_idle_thread(void)  { -	struct thread *thread = threads__findnew(0); +	struct thread *thread = threads__findnew(0, &threads, &last_match);  	if (thread == NULL ||  			thread__set_comm(thread, "[idle]")) { @@ -645,10 +501,12 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)  	char level;  	int show = 0;  	struct dso *dso = NULL; -	struct thread *thread = threads__findnew(event->ip.pid); +	struct thread *thread;  	u64 ip = event->ip.ip;  	struct map *map = NULL; +	thread = threads__findnew(event->ip.pid, &threads, &last_match); +  	dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n",  		(void *)(offset + head),  		(void *)(long)(event->header.size), @@ -719,9 +577,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)  static int  process_mmap_event(event_t *event, unsigned long offset, unsigned long head)  { -	struct thread *thread = threads__findnew(event->mmap.pid); +	struct thread *thread;  	struct map *map = map__new(&event->mmap, NULL, 0); +	thread = threads__findnew(event->mmap.pid, &threads, &last_match); +  	dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",  		(void *)(offset + head),  		(void *)(long)(event->header.size), @@ -745,8 +605,9 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)  static int  process_comm_event(event_t *event, unsigned long offset, unsigned long head)  { -	struct thread *thread = threads__findnew(event->comm.pid); +	struct thread *thread; +	thread = threads__findnew(event->comm.pid, &threads, &last_match);  	dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",  		(void *)(offset + head),  		(void *)(long)(event->header.size), @@ -765,9 +626,11 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)  static int  process_fork_event(event_t *event, unsigned long offset, unsigned long head)  { -	struct thread *thread = threads__findnew(event->fork.pid); -	struct thread *parent = threads__findnew(event->fork.ppid); +	struct thread *thread; +	struct thread *parent; +	thread = threads__findnew(event->fork.pid, &threads, &last_match); +	parent = threads__findnew(event->fork.ppid, &threads, &last_match);  	dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",  		(void *)(offset + head),  		(void *)(long)(event->header.size), @@ -1202,7 +1065,7 @@ more:  		return 0;  	if (verbose >= 3) -		threads__fprintf(stdout); +		threads__fprintf(stdout, &threads);  	if (verbose >= 2)  		dsos__fprintf(stdout);  |