aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/thread.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-12-11 11:50:36 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-12 01:42:09 -0500
commit9958e1f0aee632c3665162c9c93cf8fde8006a94 (patch)
treeffd81c34d3ca8044c3fe0d670dc1786113624bbb /tools/perf/util/thread.c
parent58e9f94138c1d9c47f6a63632ca7a78fc6dcc15f (diff)
perf symbols: Rename kthreads to kmaps, using another abstraction for it
Using a struct thread instance just to hold the kernel space maps (vmlinux + modules) is overkill and confuses people trying to understand the perf symbols abstractions. The kernel maps are really present in all threads, i.e. the kernel is a library, not a separate thread. So introduce the 'map_groups' abstraction and use it for the kernel maps, now in the kmaps global variable. It, in turn, will move, together with the threads list to the perf_file abstraction, so that we can support multiple perf_file instances, needed by perf diff. Brainstormed-with: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Eduardo Habkost <ehabkost@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1260550239-5372-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
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 603f5610861b..a1285129c831 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);