diff options
Diffstat (limited to 'tools/perf/util/thread.c')
-rw-r--r-- | tools/perf/util/thread.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 4a08dcf50b68..21b92162282b 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -31,12 +31,41 @@ static struct thread *thread__new(pid_t pid) | |||
31 | return self; | 31 | return self; |
32 | } | 32 | } |
33 | 33 | ||
34 | static void map_groups__flush(struct map_groups *self) | ||
35 | { | ||
36 | int type; | ||
37 | |||
38 | for (type = 0; type < MAP__NR_TYPES; type++) { | ||
39 | struct rb_root *root = &self->maps[type]; | ||
40 | struct rb_node *next = rb_first(root); | ||
41 | |||
42 | while (next) { | ||
43 | struct map *pos = rb_entry(next, struct map, rb_node); | ||
44 | next = rb_next(&pos->rb_node); | ||
45 | rb_erase(&pos->rb_node, root); | ||
46 | /* | ||
47 | * We may have references to this map, for | ||
48 | * instance in some hist_entry instances, so | ||
49 | * just move them to a separate list. | ||
50 | */ | ||
51 | list_add_tail(&pos->node, &self->removed_maps[pos->type]); | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | |||
34 | int thread__set_comm(struct thread *self, const char *comm) | 56 | int thread__set_comm(struct thread *self, const char *comm) |
35 | { | 57 | { |
58 | int err; | ||
59 | |||
36 | if (self->comm) | 60 | if (self->comm) |
37 | free(self->comm); | 61 | free(self->comm); |
38 | self->comm = strdup(comm); | 62 | self->comm = strdup(comm); |
39 | return self->comm ? 0 : -ENOMEM; | 63 | err = self->comm == NULL ? -ENOMEM : 0; |
64 | if (!err) { | ||
65 | self->comm_set = true; | ||
66 | map_groups__flush(&self->mg); | ||
67 | } | ||
68 | return err; | ||
40 | } | 69 | } |
41 | 70 | ||
42 | int thread__comm_len(struct thread *self) | 71 | int thread__comm_len(struct thread *self) |
@@ -50,11 +79,6 @@ int thread__comm_len(struct thread *self) | |||
50 | return self->comm_len; | 79 | return self->comm_len; |
51 | } | 80 | } |
52 | 81 | ||
53 | static const char *map_type__name[MAP__NR_TYPES] = { | ||
54 | [MAP__FUNCTION] = "Functions", | ||
55 | [MAP__VARIABLE] = "Variables", | ||
56 | }; | ||
57 | |||
58 | static size_t __map_groups__fprintf_maps(struct map_groups *self, | 82 | static size_t __map_groups__fprintf_maps(struct map_groups *self, |
59 | enum map_type type, FILE *fp) | 83 | enum map_type type, FILE *fp) |
60 | { | 84 | { |
@@ -255,11 +279,14 @@ int thread__fork(struct thread *self, struct thread *parent) | |||
255 | { | 279 | { |
256 | int i; | 280 | int i; |
257 | 281 | ||
258 | if (self->comm) | 282 | if (parent->comm_set) { |
259 | free(self->comm); | 283 | if (self->comm) |
260 | self->comm = strdup(parent->comm); | 284 | free(self->comm); |
261 | if (!self->comm) | 285 | self->comm = strdup(parent->comm); |
262 | return -ENOMEM; | 286 | if (!self->comm) |
287 | return -ENOMEM; | ||
288 | self->comm_set = true; | ||
289 | } | ||
263 | 290 | ||
264 | for (i = 0; i < MAP__NR_TYPES; ++i) | 291 | for (i = 0; i < MAP__NR_TYPES; ++i) |
265 | if (map_groups__clone(&self->mg, &parent->mg, i) < 0) | 292 | if (map_groups__clone(&self->mg, &parent->mg, i) < 0) |
@@ -282,14 +309,13 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp) | |||
282 | } | 309 | } |
283 | 310 | ||
284 | struct symbol *map_groups__find_symbol(struct map_groups *self, | 311 | struct symbol *map_groups__find_symbol(struct map_groups *self, |
285 | struct perf_session *session, | ||
286 | enum map_type type, u64 addr, | 312 | enum map_type type, u64 addr, |
287 | symbol_filter_t filter) | 313 | symbol_filter_t filter) |
288 | { | 314 | { |
289 | struct map *map = map_groups__find(self, type, addr); | 315 | struct map *map = map_groups__find(self, type, addr); |
290 | 316 | ||
291 | if (map != NULL) | 317 | if (map != NULL) |
292 | return map__find_symbol(map, session, map->map_ip(map, addr), filter); | 318 | return map__find_symbol(map, map->map_ip(map, addr), filter); |
293 | 319 | ||
294 | return NULL; | 320 | return NULL; |
295 | } | 321 | } |