aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/machine.c57
-rw-r--r--tools/perf/util/map.c14
-rw-r--r--tools/perf/util/map.h1
3 files changed, 66 insertions, 6 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5b8087728f28..5484fa4385fc 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -272,6 +272,52 @@ void machines__set_id_hdr_size(struct machines *machines, u16 id_hdr_size)
272 return; 272 return;
273} 273}
274 274
275static void machine__update_thread_pid(struct machine *machine,
276 struct thread *th, pid_t pid)
277{
278 struct thread *leader;
279
280 if (pid == th->pid_ || pid == -1 || th->pid_ != -1)
281 return;
282
283 th->pid_ = pid;
284
285 if (th->pid_ == th->tid)
286 return;
287
288 leader = machine__findnew_thread(machine, th->pid_, th->pid_);
289 if (!leader)
290 goto out_err;
291
292 if (!leader->mg)
293 leader->mg = map_groups__new();
294
295 if (!leader->mg)
296 goto out_err;
297
298 if (th->mg == leader->mg)
299 return;
300
301 if (th->mg) {
302 /*
303 * Maps are created from MMAP events which provide the pid and
304 * tid. Consequently there never should be any maps on a thread
305 * with an unknown pid. Just print an error if there are.
306 */
307 if (!map_groups__empty(th->mg))
308 pr_err("Discarding thread maps for %d:%d\n",
309 th->pid_, th->tid);
310 map_groups__delete(th->mg);
311 }
312
313 th->mg = map_groups__get(leader->mg);
314
315 return;
316
317out_err:
318 pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid);
319}
320
275static struct thread *__machine__findnew_thread(struct machine *machine, 321static struct thread *__machine__findnew_thread(struct machine *machine,
276 pid_t pid, pid_t tid, 322 pid_t pid, pid_t tid,
277 bool create) 323 bool create)
@@ -285,10 +331,10 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
285 * so most of the time we dont have to look up 331 * so most of the time we dont have to look up
286 * the full rbtree: 332 * the full rbtree:
287 */ 333 */
288 if (machine->last_match && machine->last_match->tid == tid) { 334 th = machine->last_match;
289 if (pid != -1 && pid != machine->last_match->pid_) 335 if (th && th->tid == tid) {
290 machine->last_match->pid_ = pid; 336 machine__update_thread_pid(machine, th, pid);
291 return machine->last_match; 337 return th;
292 } 338 }
293 339
294 while (*p != NULL) { 340 while (*p != NULL) {
@@ -297,8 +343,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine,
297 343
298 if (th->tid == tid) { 344 if (th->tid == tid) {
299 machine->last_match = th; 345 machine->last_match = th;
300 if (pid != -1 && pid != th->pid_) 346 machine__update_thread_pid(machine, th, pid);
301 th->pid_ = pid;
302 return th; 347 return th;
303 } 348 }
304 349
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 25c571f4cba6..7af14807ee90 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -454,6 +454,20 @@ void map_groups__exit(struct map_groups *mg)
454 } 454 }
455} 455}
456 456
457bool map_groups__empty(struct map_groups *mg)
458{
459 int i;
460
461 for (i = 0; i < MAP__NR_TYPES; ++i) {
462 if (maps__first(&mg->maps[i]))
463 return false;
464 if (!list_empty(&mg->removed_maps[i]))
465 return false;
466 }
467
468 return true;
469}
470
457struct map_groups *map_groups__new(void) 471struct map_groups *map_groups__new(void)
458{ 472{
459 struct map_groups *mg = malloc(sizeof(*mg)); 473 struct map_groups *mg = malloc(sizeof(*mg));
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 7758c72522ef..5806a906198b 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -66,6 +66,7 @@ struct map_groups {
66 66
67struct map_groups *map_groups__new(void); 67struct map_groups *map_groups__new(void);
68void map_groups__delete(struct map_groups *mg); 68void map_groups__delete(struct map_groups *mg);
69bool map_groups__empty(struct map_groups *mg);
69 70
70static inline struct map_groups *map_groups__get(struct map_groups *mg) 71static inline struct map_groups *map_groups__get(struct map_groups *mg)
71{ 72{