8 static struct thread *thread__new(pid_t pid)
10 struct thread *self = malloc(sizeof(*self));
14 self->comm = malloc(32);
16 snprintf(self->comm, 32, ":%d", self->pid);
17 INIT_LIST_HEAD(&self->maps);
23 int thread__set_comm(struct thread *self, const char *comm)
27 self->comm = strdup(comm);
28 return self->comm ? 0 : -ENOMEM;
31 static size_t thread__fprintf(struct thread *self, FILE *fp)
34 size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
36 list_for_each_entry(pos, &self->maps, node)
37 ret += map__fprintf(pos, fp);
43 threads__findnew(pid_t pid, struct rb_root *threads, struct thread **last_match)
45 struct rb_node **p = &threads->rb_node;
46 struct rb_node *parent = NULL;
50 * Font-end cache - PID lookups come in blocks,
51 * so most of the time we dont have to look up
54 if (*last_match && (*last_match)->pid == pid)
59 th = rb_entry(parent, struct thread, rb_node);
72 th = thread__new(pid);
74 rb_link_node(&th->rb_node, parent, p);
75 rb_insert_color(&th->rb_node, threads);
82 void thread__insert_map(struct thread *self, struct map *map)
84 struct map *pos, *tmp;
86 list_for_each_entry_safe(pos, tmp, &self->maps, node) {
87 if (map__overlap(pos, map)) {
88 list_del_init(&pos->node);
94 list_add_tail(&map->node, &self->maps);
97 int thread__fork(struct thread *self, struct thread *parent)
103 self->comm = strdup(parent->comm);
107 list_for_each_entry(map, &parent->maps, node) {
108 struct map *new = map__clone(map);
111 thread__insert_map(self, new);
117 struct map *thread__find_map(struct thread *self, u64 ip)
124 list_for_each_entry(pos, &self->maps, node)
125 if (ip >= pos->start && ip <= pos->end)
131 size_t threads__fprintf(FILE *fp, struct rb_root *threads)
136 for (nd = rb_first(threads); nd; nd = rb_next(nd)) {
137 struct thread *pos = rb_entry(nd, struct thread, rb_node);
139 ret += thread__fprintf(pos, fp);