diff options
Diffstat (limited to 'tools/perf/util/thread.c')
| -rw-r--r-- | tools/perf/util/thread.c | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 1dbcd3c8dee0..68b65b10579b 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
| @@ -46,6 +46,8 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
| 46 | thread->cpu = -1; | 46 | thread->cpu = -1; |
| 47 | INIT_LIST_HEAD(&thread->namespaces_list); | 47 | INIT_LIST_HEAD(&thread->namespaces_list); |
| 48 | INIT_LIST_HEAD(&thread->comm_list); | 48 | INIT_LIST_HEAD(&thread->comm_list); |
| 49 | init_rwsem(&thread->namespaces_lock); | ||
| 50 | init_rwsem(&thread->comm_lock); | ||
| 49 | 51 | ||
| 50 | comm_str = malloc(32); | 52 | comm_str = malloc(32); |
| 51 | if (!comm_str) | 53 | if (!comm_str) |
| @@ -84,18 +86,26 @@ void thread__delete(struct thread *thread) | |||
| 84 | map_groups__put(thread->mg); | 86 | map_groups__put(thread->mg); |
| 85 | thread->mg = NULL; | 87 | thread->mg = NULL; |
| 86 | } | 88 | } |
| 89 | down_write(&thread->namespaces_lock); | ||
| 87 | list_for_each_entry_safe(namespaces, tmp_namespaces, | 90 | list_for_each_entry_safe(namespaces, tmp_namespaces, |
| 88 | &thread->namespaces_list, list) { | 91 | &thread->namespaces_list, list) { |
| 89 | list_del(&namespaces->list); | 92 | list_del(&namespaces->list); |
| 90 | namespaces__free(namespaces); | 93 | namespaces__free(namespaces); |
| 91 | } | 94 | } |
| 95 | up_write(&thread->namespaces_lock); | ||
| 96 | |||
| 97 | down_write(&thread->comm_lock); | ||
| 92 | list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { | 98 | list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { |
| 93 | list_del(&comm->list); | 99 | list_del(&comm->list); |
| 94 | comm__free(comm); | 100 | comm__free(comm); |
| 95 | } | 101 | } |
| 102 | up_write(&thread->comm_lock); | ||
| 103 | |||
| 96 | unwind__finish_access(thread); | 104 | unwind__finish_access(thread); |
| 97 | nsinfo__zput(thread->nsinfo); | 105 | nsinfo__zput(thread->nsinfo); |
| 98 | 106 | ||
| 107 | exit_rwsem(&thread->namespaces_lock); | ||
| 108 | exit_rwsem(&thread->comm_lock); | ||
| 99 | free(thread); | 109 | free(thread); |
| 100 | } | 110 | } |
| 101 | 111 | ||
| @@ -126,8 +136,8 @@ struct namespaces *thread__namespaces(const struct thread *thread) | |||
| 126 | return list_first_entry(&thread->namespaces_list, struct namespaces, list); | 136 | return list_first_entry(&thread->namespaces_list, struct namespaces, list); |
| 127 | } | 137 | } |
| 128 | 138 | ||
| 129 | int thread__set_namespaces(struct thread *thread, u64 timestamp, | 139 | static int __thread__set_namespaces(struct thread *thread, u64 timestamp, |
| 130 | struct namespaces_event *event) | 140 | struct namespaces_event *event) |
| 131 | { | 141 | { |
| 132 | struct namespaces *new, *curr = thread__namespaces(thread); | 142 | struct namespaces *new, *curr = thread__namespaces(thread); |
| 133 | 143 | ||
| @@ -150,6 +160,17 @@ int thread__set_namespaces(struct thread *thread, u64 timestamp, | |||
| 150 | return 0; | 160 | return 0; |
| 151 | } | 161 | } |
| 152 | 162 | ||
| 163 | int thread__set_namespaces(struct thread *thread, u64 timestamp, | ||
| 164 | struct namespaces_event *event) | ||
| 165 | { | ||
| 166 | int ret; | ||
| 167 | |||
| 168 | down_write(&thread->namespaces_lock); | ||
| 169 | ret = __thread__set_namespaces(thread, timestamp, event); | ||
| 170 | up_write(&thread->namespaces_lock); | ||
| 171 | return ret; | ||
| 172 | } | ||
| 173 | |||
| 153 | struct comm *thread__comm(const struct thread *thread) | 174 | struct comm *thread__comm(const struct thread *thread) |
| 154 | { | 175 | { |
| 155 | if (list_empty(&thread->comm_list)) | 176 | if (list_empty(&thread->comm_list)) |
| @@ -171,8 +192,8 @@ struct comm *thread__exec_comm(const struct thread *thread) | |||
| 171 | return last; | 192 | return last; |
| 172 | } | 193 | } |
| 173 | 194 | ||
| 174 | int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | 195 | static int ____thread__set_comm(struct thread *thread, const char *str, |
| 175 | bool exec) | 196 | u64 timestamp, bool exec) |
| 176 | { | 197 | { |
| 177 | struct comm *new, *curr = thread__comm(thread); | 198 | struct comm *new, *curr = thread__comm(thread); |
| 178 | 199 | ||
| @@ -196,6 +217,17 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | |||
| 196 | return 0; | 217 | return 0; |
| 197 | } | 218 | } |
| 198 | 219 | ||
| 220 | int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, | ||
| 221 | bool exec) | ||
| 222 | { | ||
| 223 | int ret; | ||
| 224 | |||
| 225 | down_write(&thread->comm_lock); | ||
| 226 | ret = ____thread__set_comm(thread, str, timestamp, exec); | ||
| 227 | up_write(&thread->comm_lock); | ||
| 228 | return ret; | ||
| 229 | } | ||
| 230 | |||
| 199 | int thread__set_comm_from_proc(struct thread *thread) | 231 | int thread__set_comm_from_proc(struct thread *thread) |
| 200 | { | 232 | { |
| 201 | char path[64]; | 233 | char path[64]; |
| @@ -213,7 +245,7 @@ int thread__set_comm_from_proc(struct thread *thread) | |||
| 213 | return err; | 245 | return err; |
| 214 | } | 246 | } |
| 215 | 247 | ||
| 216 | const char *thread__comm_str(const struct thread *thread) | 248 | static const char *__thread__comm_str(const struct thread *thread) |
| 217 | { | 249 | { |
| 218 | const struct comm *comm = thread__comm(thread); | 250 | const struct comm *comm = thread__comm(thread); |
| 219 | 251 | ||
| @@ -223,6 +255,17 @@ const char *thread__comm_str(const struct thread *thread) | |||
| 223 | return comm__str(comm); | 255 | return comm__str(comm); |
| 224 | } | 256 | } |
| 225 | 257 | ||
| 258 | const char *thread__comm_str(const struct thread *thread) | ||
| 259 | { | ||
| 260 | const char *str; | ||
| 261 | |||
| 262 | down_read((struct rw_semaphore *)&thread->comm_lock); | ||
| 263 | str = __thread__comm_str(thread); | ||
| 264 | up_read((struct rw_semaphore *)&thread->comm_lock); | ||
| 265 | |||
| 266 | return str; | ||
| 267 | } | ||
| 268 | |||
| 226 | /* CHECKME: it should probably better return the max comm len from its comm list */ | 269 | /* CHECKME: it should probably better return the max comm len from its comm list */ |
| 227 | int thread__comm_len(struct thread *thread) | 270 | int thread__comm_len(struct thread *thread) |
| 228 | { | 271 | { |
| @@ -265,7 +308,7 @@ static int __thread__prepare_access(struct thread *thread) | |||
| 265 | struct maps *maps = &thread->mg->maps[i]; | 308 | struct maps *maps = &thread->mg->maps[i]; |
| 266 | struct map *map; | 309 | struct map *map; |
| 267 | 310 | ||
| 268 | pthread_rwlock_rdlock(&maps->lock); | 311 | down_read(&maps->lock); |
| 269 | 312 | ||
| 270 | for (map = maps__first(maps); map; map = map__next(map)) { | 313 | for (map = maps__first(maps); map; map = map__next(map)) { |
| 271 | err = unwind__prepare_access(thread, map, &initialized); | 314 | err = unwind__prepare_access(thread, map, &initialized); |
| @@ -273,7 +316,7 @@ static int __thread__prepare_access(struct thread *thread) | |||
| 273 | break; | 316 | break; |
| 274 | } | 317 | } |
| 275 | 318 | ||
| 276 | pthread_rwlock_unlock(&maps->lock); | 319 | up_read(&maps->lock); |
| 277 | } | 320 | } |
| 278 | 321 | ||
| 279 | return err; | 322 | return err; |
