diff options
Diffstat (limited to 'tools/perf/util/machine.c')
| -rw-r--r-- | tools/perf/util/machine.c | 79 | 
1 files changed, 62 insertions, 17 deletions
| diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e7b4a8b513f2..b300a3973448 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -408,23 +408,16 @@ out_err:  }  /* - * Caller must eventually drop thread->refcnt returned with a successful - * lookup/new thread inserted. + * Front-end cache - TID lookups come in blocks, + * so most of the time we dont have to look up + * the full rbtree:   */ -static struct thread *____machine__findnew_thread(struct machine *machine, -						  struct threads *threads, -						  pid_t pid, pid_t tid, -						  bool create) +static struct thread* +__threads__get_last_match(struct threads *threads, struct machine *machine, +			  int pid, int tid)  { -	struct rb_node **p = &threads->entries.rb_node; -	struct rb_node *parent = NULL;  	struct thread *th; -	/* -	 * Front-end cache - TID lookups come in blocks, -	 * so most of the time we dont have to look up -	 * the full rbtree: -	 */  	th = threads->last_match;  	if (th != NULL) {  		if (th->tid == tid) { @@ -435,12 +428,57 @@ static struct thread *____machine__findnew_thread(struct machine *machine,  		threads->last_match = NULL;  	} +	return NULL; +} + +static struct thread* +threads__get_last_match(struct threads *threads, struct machine *machine, +			int pid, int tid) +{ +	struct thread *th = NULL; + +	if (perf_singlethreaded) +		th = __threads__get_last_match(threads, machine, pid, tid); + +	return th; +} + +static void +__threads__set_last_match(struct threads *threads, struct thread *th) +{ +	threads->last_match = th; +} + +static void +threads__set_last_match(struct threads *threads, struct thread *th) +{ +	if (perf_singlethreaded) +		__threads__set_last_match(threads, th); +} + +/* + * Caller must eventually drop thread->refcnt returned with a successful + * lookup/new thread inserted. + */ +static struct thread *____machine__findnew_thread(struct machine *machine, +						  struct threads *threads, +						  pid_t pid, pid_t tid, +						  bool create) +{ +	struct rb_node **p = &threads->entries.rb_node; +	struct rb_node *parent = NULL; +	struct thread *th; + +	th = threads__get_last_match(threads, machine, pid, tid); +	if (th) +		return th; +  	while (*p != NULL) {  		parent = *p;  		th = rb_entry(parent, struct thread, rb_node);  		if (th->tid == tid) { -			threads->last_match = th; +			threads__set_last_match(threads, th);  			machine__update_thread_pid(machine, th, pid);  			return thread__get(th);  		} @@ -477,7 +515,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,  		 * It is now in the rbtree, get a ref  		 */  		thread__get(th); -		threads->last_match = th; +		threads__set_last_match(threads, th);  		++threads->nr;  	} @@ -1635,7 +1673,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,  	struct threads *threads = machine__threads(machine, th->tid);  	if (threads->last_match == th) -		threads->last_match = NULL; +		threads__set_last_match(threads, NULL);  	BUG_ON(refcount_read(&th->refcnt) == 0);  	if (lock) @@ -2272,6 +2310,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)  {  	struct callchain_cursor *cursor = arg;  	const char *srcline = NULL; +	u64 addr;  	if (symbol_conf.hide_unresolved && entry->sym == NULL)  		return 0; @@ -2279,7 +2318,13 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)  	if (append_inlines(cursor, entry->map, entry->sym, entry->ip) == 0)  		return 0; -	srcline = callchain_srcline(entry->map, entry->sym, entry->ip); +	/* +	 * Convert entry->ip from a virtual address to an offset in +	 * its corresponding binary. +	 */ +	addr = map__map_ip(entry->map, entry->ip); + +	srcline = callchain_srcline(entry->map, entry->sym, addr);  	return callchain_cursor_append(cursor, entry->ip,  				       entry->map, entry->sym,  				       false, NULL, 0, 0, 0, srcline); |