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.c62
1 files changed, 35 insertions, 27 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 603f5610861..a1285129c83 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -9,11 +9,9 @@
9static struct rb_root threads; 9static struct rb_root threads;
10static struct thread *last_match; 10static struct thread *last_match;
11 11
12void thread__init(struct thread *self, pid_t pid) 12void map_groups__init(struct map_groups *self)
13{ 13{
14 int i; 14 int i;
15 self->pid = pid;
16 self->comm = NULL;
17 for (i = 0; i < MAP__NR_TYPES; ++i) { 15 for (i = 0; i < MAP__NR_TYPES; ++i) {
18 self->maps[i] = RB_ROOT; 16 self->maps[i] = RB_ROOT;
19 INIT_LIST_HEAD(&self->removed_maps[i]); 17 INIT_LIST_HEAD(&self->removed_maps[i]);
@@ -25,7 +23,8 @@ static struct thread *thread__new(pid_t pid)
25 struct thread *self = zalloc(sizeof(*self)); 23 struct thread *self = zalloc(sizeof(*self));
26 24
27 if (self != NULL) { 25 if (self != NULL) {
28 thread__init(self, pid); 26 map_groups__init(&self->mg);
27 self->pid = pid;
29 self->comm = malloc(32); 28 self->comm = malloc(32);
30 if (self->comm) 29 if (self->comm)
31 snprintf(self->comm, 32, ":%d", self->pid); 30 snprintf(self->comm, 32, ":%d", self->pid);
@@ -57,8 +56,8 @@ static const char *map_type__name[MAP__NR_TYPES] = {
57 [MAP__FUNCTION] = "Functions", 56 [MAP__FUNCTION] = "Functions",
58}; 57};
59 58
60static size_t __thread__fprintf_maps(struct thread *self, 59static size_t __map_groups__fprintf_maps(struct map_groups *self,
61 enum map_type type, FILE *fp) 60 enum map_type type, FILE *fp)
62{ 61{
63 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); 62 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
64 struct rb_node *nd; 63 struct rb_node *nd;
@@ -76,16 +75,16 @@ static size_t __thread__fprintf_maps(struct thread *self,
76 return printed; 75 return printed;
77} 76}
78 77
79size_t thread__fprintf_maps(struct thread *self, FILE *fp) 78size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp)
80{ 79{
81 size_t printed = 0, i; 80 size_t printed = 0, i;
82 for (i = 0; i < MAP__NR_TYPES; ++i) 81 for (i = 0; i < MAP__NR_TYPES; ++i)
83 printed += __thread__fprintf_maps(self, i, fp); 82 printed += __map_groups__fprintf_maps(self, i, fp);
84 return printed; 83 return printed;
85} 84}
86 85
87static size_t __thread__fprintf_removed_maps(struct thread *self, 86static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
88 enum map_type type, FILE *fp) 87 enum map_type type, FILE *fp)
89{ 88{
90 struct map *pos; 89 struct map *pos;
91 size_t printed = 0; 90 size_t printed = 0;
@@ -101,20 +100,25 @@ static size_t __thread__fprintf_removed_maps(struct thread *self,
101 return printed; 100 return printed;
102} 101}
103 102
104static size_t thread__fprintf_removed_maps(struct thread *self, FILE *fp) 103static size_t map_groups__fprintf_removed_maps(struct map_groups *self, FILE *fp)
105{ 104{
106 size_t printed = 0, i; 105 size_t printed = 0, i;
107 for (i = 0; i < MAP__NR_TYPES; ++i) 106 for (i = 0; i < MAP__NR_TYPES; ++i)
108 printed += __thread__fprintf_removed_maps(self, i, fp); 107 printed += __map_groups__fprintf_removed_maps(self, i, fp);
109 return printed; 108 return printed;
110} 109}
111 110
112static size_t thread__fprintf(struct thread *self, FILE *fp) 111static size_t map_groups__fprintf(struct map_groups *self, FILE *fp)
113{ 112{
114 size_t printed = fprintf(fp, "Thread %d %s\n", self->pid, self->comm); 113 size_t printed = map_groups__fprintf_maps(self, fp);
115 printed += thread__fprintf_removed_maps(self, fp);
116 printed += fprintf(fp, "Removed maps:\n"); 114 printed += fprintf(fp, "Removed maps:\n");
117 return printed + thread__fprintf_removed_maps(self, fp); 115 return printed + map_groups__fprintf_removed_maps(self, fp);
116}
117
118static size_t thread__fprintf(struct thread *self, FILE *fp)
119{
120 return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) +
121 map_groups__fprintf(&self->mg, fp);
118} 122}
119 123
120struct thread *threads__findnew(pid_t pid) 124struct thread *threads__findnew(pid_t pid)
@@ -168,7 +172,8 @@ struct thread *register_idle_thread(void)
168 return thread; 172 return thread;
169} 173}
170 174
171static void thread__remove_overlappings(struct thread *self, struct map *map) 175static void map_groups__remove_overlappings(struct map_groups *self,
176 struct map *map)
172{ 177{
173 struct rb_root *root = &self->maps[map->type]; 178 struct rb_root *root = &self->maps[map->type];
174 struct rb_node *next = rb_first(root); 179 struct rb_node *next = rb_first(root);
@@ -238,12 +243,15 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
238 243
239void thread__insert_map(struct thread *self, struct map *map) 244void thread__insert_map(struct thread *self, struct map *map)
240{ 245{
241 thread__remove_overlappings(self, map); 246 map_groups__remove_overlappings(&self->mg, map);
242 maps__insert(&self->maps[map->type], map); 247 map_groups__insert(&self->mg, map);
243} 248}
244 249
245static int thread__clone_maps(struct thread *self, struct thread *parent, 250/*
246 enum map_type type) 251 * XXX This should not really _copy_ te maps, but refcount them.
252 */
253static int map_groups__clone(struct map_groups *self,
254 struct map_groups *parent, enum map_type type)
247{ 255{
248 struct rb_node *nd; 256 struct rb_node *nd;
249 for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) { 257 for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
@@ -251,7 +259,7 @@ static int thread__clone_maps(struct thread *self, struct thread *parent,
251 struct map *new = map__clone(map); 259 struct map *new = map__clone(map);
252 if (new == NULL) 260 if (new == NULL)
253 return -ENOMEM; 261 return -ENOMEM;
254 thread__insert_map(self, new); 262 map_groups__insert(self, new);
255 } 263 }
256 return 0; 264 return 0;
257} 265}
@@ -267,7 +275,7 @@ int thread__fork(struct thread *self, struct thread *parent)
267 return -ENOMEM; 275 return -ENOMEM;
268 276
269 for (i = 0; i < MAP__NR_TYPES; ++i) 277 for (i = 0; i < MAP__NR_TYPES; ++i)
270 if (thread__clone_maps(self, parent, i) < 0) 278 if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
271 return -ENOMEM; 279 return -ENOMEM;
272 return 0; 280 return 0;
273} 281}
@@ -286,11 +294,11 @@ size_t threads__fprintf(FILE *fp)
286 return ret; 294 return ret;
287} 295}
288 296
289struct symbol *thread__find_symbol(struct thread *self, 297struct symbol *map_groups__find_symbol(struct map_groups *self,
290 enum map_type type, u64 addr, 298 enum map_type type, u64 addr,
291 symbol_filter_t filter) 299 symbol_filter_t filter)
292{ 300{
293 struct map *map = thread__find_map(self, type, addr); 301 struct map *map = map_groups__find(self, type, addr);
294 302
295 if (map != NULL) 303 if (map != NULL)
296 return map__find_symbol(map, map->map_ip(map, addr), filter); 304 return map__find_symbol(map, map->map_ip(map, addr), filter);