diff options
Diffstat (limited to 'tools/perf/util/thread.c')
-rw-r--r-- | tools/perf/util/thread.c | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 45fcb715a36b..f5af87f66663 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -14,13 +14,12 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine) { - struct thread *leader; pid_t pid = thread->pid_; if (pid == thread->tid || pid == -1) { thread->mg = map_groups__new(machine); } else { - leader = __machine__findnew_thread(machine, pid, pid); + struct thread *leader = __machine__findnew_thread(machine, pid, pid); if (leader) { thread->mg = map_groups__get(leader->mg); thread__put(leader); @@ -43,9 +42,6 @@ struct thread *thread__new(pid_t pid, pid_t tid) thread->cpu = -1; INIT_LIST_HEAD(&thread->comm_list); - if (unwind__prepare_access(thread) < 0) - goto err_thread; - comm_str = malloc(32); if (!comm_str) goto err_thread; @@ -133,11 +129,10 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, bool exec) { struct comm *new, *curr = thread__comm(thread); - int err; /* Override the default :tid entry */ if (!thread->comm_set) { - err = comm__override(curr, str, timestamp, exec); + int err = comm__override(curr, str, timestamp, exec); if (err) return err; } else { @@ -201,10 +196,51 @@ size_t thread__fprintf(struct thread *thread, FILE *fp) map_groups__fprintf(thread->mg, fp); } -void thread__insert_map(struct thread *thread, struct map *map) +int thread__insert_map(struct thread *thread, struct map *map) { + int ret; + + ret = unwind__prepare_access(thread, map, NULL); + if (ret) + return ret; + map_groups__fixup_overlappings(thread->mg, map, stderr); map_groups__insert(thread->mg, map); + + return 0; +} + +static int __thread__prepare_access(struct thread *thread) +{ + bool initialized = false; + int i, err = 0; + + for (i = 0; i < MAP__NR_TYPES; ++i) { + struct maps *maps = &thread->mg->maps[i]; + struct map *map; + + pthread_rwlock_rdlock(&maps->lock); + + for (map = maps__first(maps); map; map = map__next(map)) { + err = unwind__prepare_access(thread, map, &initialized); + if (err || initialized) + break; + } + + pthread_rwlock_unlock(&maps->lock); + } + + return err; +} + +static int thread__prepare_access(struct thread *thread) +{ + int err = 0; + + if (symbol_conf.use_callchain) + err = __thread__prepare_access(thread); + + return err; } static int thread__clone_map_groups(struct thread *thread, @@ -214,7 +250,7 @@ static int thread__clone_map_groups(struct thread *thread, /* This is new thread, we share map groups for process. */ if (thread->pid_ == parent->pid_) - return 0; + return thread__prepare_access(thread); if (thread->mg == parent->mg) { pr_debug("broken map groups on thread %d/%d parent %d/%d\n", @@ -224,7 +260,7 @@ static int thread__clone_map_groups(struct thread *thread, /* But this one is new process, copy maps. */ for (i = 0; i < MAP__NR_TYPES; ++i) - if (map_groups__clone(thread->mg, parent->mg, i) < 0) + if (map_groups__clone(thread, parent->mg, i) < 0) return -ENOMEM; return 0; @@ -232,10 +268,9 @@ static int thread__clone_map_groups(struct thread *thread, int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp) { - int err; - if (parent->comm_set) { const char *comm = thread__comm_str(parent); + int err; if (!comm) return -ENOMEM; err = thread__set_comm(thread, comm, timestamp); @@ -265,3 +300,14 @@ void thread__find_cpumode_addr_location(struct thread *thread, break; } } + +struct thread *thread__main_thread(struct machine *machine, struct thread *thread) +{ + if (thread->pid_ == thread->tid) + return thread__get(thread); + + if (thread->pid_ == -1) + return NULL; + + return machine__find_thread(machine, thread->pid_, thread->pid_); +} |