10 /* Skip "." and ".." directories */
11 static int filter(const struct dirent
*dir
)
13 if (dir
->d_name
[0] == '.')
19 int find_all_tid(int pid
, pid_t
** all_tid
)
23 struct dirent
**namelist
= NULL
;
27 sprintf(name
, "/proc/%d/task", pid
);
28 items
= scandir(name
, &namelist
, filter
, NULL
);
31 *all_tid
= malloc(sizeof(pid_t
) * items
);
37 for (i
= 0; i
< items
; i
++)
38 (*all_tid
)[i
] = atoi(namelist
[i
]->d_name
);
43 for (i
=0; i
<items
; i
++)
50 static struct thread
*thread__new(pid_t pid
)
52 struct thread
*self
= zalloc(sizeof(*self
));
55 map_groups__init(&self
->mg
);
57 self
->comm
= malloc(32);
59 snprintf(self
->comm
, 32, ":%d", self
->pid
);
65 int thread__set_comm(struct thread
*self
, const char *comm
)
71 self
->comm
= strdup(comm
);
72 err
= self
->comm
== NULL
? -ENOMEM
: 0;
74 self
->comm_set
= true;
75 map_groups__flush(&self
->mg
);
80 int thread__comm_len(struct thread
*self
)
82 if (!self
->comm_len
) {
85 self
->comm_len
= strlen(self
->comm
);
88 return self
->comm_len
;
91 static size_t thread__fprintf(struct thread
*self
, FILE *fp
)
93 return fprintf(fp
, "Thread %d %s\n", self
->pid
, self
->comm
) +
94 map_groups__fprintf(&self
->mg
, verbose
, fp
);
97 struct thread
*perf_session__findnew(struct perf_session
*self
, pid_t pid
)
99 struct rb_node
**p
= &self
->threads
.rb_node
;
100 struct rb_node
*parent
= NULL
;
104 * Font-end cache - PID lookups come in blocks,
105 * so most of the time we dont have to look up
108 if (self
->last_match
&& self
->last_match
->pid
== pid
)
109 return self
->last_match
;
113 th
= rb_entry(parent
, struct thread
, rb_node
);
115 if (th
->pid
== pid
) {
116 self
->last_match
= th
;
126 th
= thread__new(pid
);
128 rb_link_node(&th
->rb_node
, parent
, p
);
129 rb_insert_color(&th
->rb_node
, &self
->threads
);
130 self
->last_match
= th
;
136 void thread__insert_map(struct thread
*self
, struct map
*map
)
138 map_groups__fixup_overlappings(&self
->mg
, map
, verbose
, stderr
);
139 map_groups__insert(&self
->mg
, map
);
142 int thread__fork(struct thread
*self
, struct thread
*parent
)
146 if (parent
->comm_set
) {
149 self
->comm
= strdup(parent
->comm
);
152 self
->comm_set
= true;
155 for (i
= 0; i
< MAP__NR_TYPES
; ++i
)
156 if (map_groups__clone(&self
->mg
, &parent
->mg
, i
) < 0)
161 size_t perf_session__fprintf(struct perf_session
*self
, FILE *fp
)
166 for (nd
= rb_first(&self
->threads
); nd
; nd
= rb_next(nd
)) {
167 struct thread
*pos
= rb_entry(nd
, struct thread
, rb_node
);
169 ret
+= thread__fprintf(pos
, fp
);