aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/thread.c')
-rw-r--r--tools/perf/util/thread.c93
1 files changed, 74 insertions, 19 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 4a08dcf50b68..fa968312ee7d 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
34static 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
34int thread__set_comm(struct thread *self, const char *comm) 56int 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
42int thread__comm_len(struct thread *self) 71int thread__comm_len(struct thread *self)
@@ -50,13 +79,8 @@ int thread__comm_len(struct thread *self)
50 return self->comm_len; 79 return self->comm_len;
51} 80}
52 81
53static const char *map_type__name[MAP__NR_TYPES] = { 82size_t __map_groups__fprintf_maps(struct map_groups *self,
54 [MAP__FUNCTION] = "Functions", 83 enum map_type type, FILE *fp)
55 [MAP__VARIABLE] = "Variables",
56};
57
58static size_t __map_groups__fprintf_maps(struct map_groups *self,
59 enum map_type type, FILE *fp)
60{ 84{
61 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); 85 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
62 struct rb_node *nd; 86 struct rb_node *nd;
@@ -65,7 +89,7 @@ static size_t __map_groups__fprintf_maps(struct map_groups *self,
65 struct map *pos = rb_entry(nd, struct map, rb_node); 89 struct map *pos = rb_entry(nd, struct map, rb_node);
66 printed += fprintf(fp, "Map:"); 90 printed += fprintf(fp, "Map:");
67 printed += map__fprintf(pos, fp); 91 printed += map__fprintf(pos, fp);
68 if (verbose > 1) { 92 if (verbose > 2) {
69 printed += dso__fprintf(pos->dso, type, fp); 93 printed += dso__fprintf(pos->dso, type, fp);
70 printed += fprintf(fp, "--\n"); 94 printed += fprintf(fp, "--\n");
71 } 95 }
@@ -159,8 +183,8 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
159 return th; 183 return th;
160} 184}
161 185
162static void map_groups__remove_overlappings(struct map_groups *self, 186static int map_groups__fixup_overlappings(struct map_groups *self,
163 struct map *map) 187 struct map *map)
164{ 188{
165 struct rb_root *root = &self->maps[map->type]; 189 struct rb_root *root = &self->maps[map->type];
166 struct rb_node *next = rb_first(root); 190 struct rb_node *next = rb_first(root);
@@ -185,7 +209,36 @@ static void map_groups__remove_overlappings(struct map_groups *self,
185 * list. 209 * list.
186 */ 210 */
187 list_add_tail(&pos->node, &self->removed_maps[map->type]); 211 list_add_tail(&pos->node, &self->removed_maps[map->type]);
212 /*
213 * Now check if we need to create new maps for areas not
214 * overlapped by the new map:
215 */
216 if (map->start > pos->start) {
217 struct map *before = map__clone(pos);
218
219 if (before == NULL)
220 return -ENOMEM;
221
222 before->end = map->start - 1;
223 map_groups__insert(self, before);
224 if (verbose >= 2)
225 map__fprintf(before, stderr);
226 }
227
228 if (map->end < pos->end) {
229 struct map *after = map__clone(pos);
230
231 if (after == NULL)
232 return -ENOMEM;
233
234 after->start = map->end + 1;
235 map_groups__insert(self, after);
236 if (verbose >= 2)
237 map__fprintf(after, stderr);
238 }
188 } 239 }
240
241 return 0;
189} 242}
190 243
191void maps__insert(struct rb_root *maps, struct map *map) 244void maps__insert(struct rb_root *maps, struct map *map)
@@ -230,7 +283,7 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
230 283
231void thread__insert_map(struct thread *self, struct map *map) 284void thread__insert_map(struct thread *self, struct map *map)
232{ 285{
233 map_groups__remove_overlappings(&self->mg, map); 286 map_groups__fixup_overlappings(&self->mg, map);
234 map_groups__insert(&self->mg, map); 287 map_groups__insert(&self->mg, map);
235} 288}
236 289
@@ -255,11 +308,14 @@ int thread__fork(struct thread *self, struct thread *parent)
255{ 308{
256 int i; 309 int i;
257 310
258 if (self->comm) 311 if (parent->comm_set) {
259 free(self->comm); 312 if (self->comm)
260 self->comm = strdup(parent->comm); 313 free(self->comm);
261 if (!self->comm) 314 self->comm = strdup(parent->comm);
262 return -ENOMEM; 315 if (!self->comm)
316 return -ENOMEM;
317 self->comm_set = true;
318 }
263 319
264 for (i = 0; i < MAP__NR_TYPES; ++i) 320 for (i = 0; i < MAP__NR_TYPES; ++i)
265 if (map_groups__clone(&self->mg, &parent->mg, i) < 0) 321 if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
@@ -282,14 +338,13 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp)
282} 338}
283 339
284struct symbol *map_groups__find_symbol(struct map_groups *self, 340struct symbol *map_groups__find_symbol(struct map_groups *self,
285 struct perf_session *session,
286 enum map_type type, u64 addr, 341 enum map_type type, u64 addr,
287 symbol_filter_t filter) 342 symbol_filter_t filter)
288{ 343{
289 struct map *map = map_groups__find(self, type, addr); 344 struct map *map = map_groups__find(self, type, addr);
290 345
291 if (map != NULL) 346 if (map != NULL)
292 return map__find_symbol(map, session, map->map_ip(map, addr), filter); 347 return map__find_symbol(map, map->map_ip(map, addr), filter);
293 348
294 return NULL; 349 return NULL;
295} 350}