9 static struct thread
*thread__new(pid_t pid
)
11 struct thread
*self
= calloc(1, sizeof(*self
));
15 self
->comm
= malloc(32);
17 snprintf(self
->comm
, 32, ":%d", self
->pid
);
18 INIT_LIST_HEAD(&self
->maps
);
24 int thread__set_comm(struct thread
*self
, const char *comm
)
28 self
->comm
= strdup(comm
);
29 return self
->comm
? 0 : -ENOMEM
;
32 static size_t thread__fprintf(struct thread
*self
, FILE *fp
)
35 size_t ret
= fprintf(fp
, "Thread %d %s\n", self
->pid
, self
->comm
);
37 list_for_each_entry(pos
, &self
->maps
, node
)
38 ret
+= map__fprintf(pos
, fp
);
44 threads__findnew(pid_t pid
, struct rb_root
*threads
, struct thread
**last_match
)
46 struct rb_node
**p
= &threads
->rb_node
;
47 struct rb_node
*parent
= NULL
;
51 * Font-end cache - PID lookups come in blocks,
52 * so most of the time we dont have to look up
55 if (*last_match
&& (*last_match
)->pid
== pid
)
60 th
= rb_entry(parent
, struct thread
, rb_node
);
73 th
= thread__new(pid
);
75 rb_link_node(&th
->rb_node
, parent
, p
);
76 rb_insert_color(&th
->rb_node
, threads
);
84 register_idle_thread(struct rb_root
*threads
, struct thread
**last_match
)
86 struct thread
*thread
= threads__findnew(0, threads
, last_match
);
88 if (!thread
|| thread__set_comm(thread
, "swapper")) {
89 fprintf(stderr
, "problem inserting idle task.\n");
96 void thread__insert_map(struct thread
*self
, struct map
*map
)
98 struct map
*pos
, *tmp
;
100 list_for_each_entry_safe(pos
, tmp
, &self
->maps
, node
) {
101 if (map__overlap(pos
, map
)) {
103 printf("overlapping maps:\n");
104 map__fprintf(map
, stdout
);
105 map__fprintf(pos
, stdout
);
108 if (map
->start
<= pos
->start
&& map
->end
> pos
->start
)
109 pos
->start
= map
->end
;
111 if (map
->end
>= pos
->end
&& map
->start
< pos
->end
)
112 pos
->end
= map
->start
;
115 printf("after collision:\n");
116 map__fprintf(pos
, stdout
);
119 if (pos
->start
>= pos
->end
) {
120 list_del_init(&pos
->node
);
126 list_add_tail(&map
->node
, &self
->maps
);
129 int thread__fork(struct thread
*self
, struct thread
*parent
)
135 self
->comm
= strdup(parent
->comm
);
139 list_for_each_entry(map
, &parent
->maps
, node
) {
140 struct map
*new = map__clone(map
);
143 thread__insert_map(self
, new);
149 struct map
*thread__find_map(struct thread
*self
, u64 ip
)
156 list_for_each_entry(pos
, &self
->maps
, node
)
157 if (ip
>= pos
->start
&& ip
<= pos
->end
)
163 size_t threads__fprintf(FILE *fp
, struct rb_root
*threads
)
168 for (nd
= rb_first(threads
); nd
; nd
= rb_next(nd
)) {
169 struct thread
*pos
= rb_entry(nd
, struct thread
, rb_node
);
171 ret
+= thread__fprintf(pos
, fp
);