diff options
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r-- | tools/perf/util/machine.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9e0f60a7e7b3..24f8c978cfd4 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include "unwind.h" | 14 | #include "unwind.h" |
15 | #include "linux/hash.h" | 15 | #include "linux/hash.h" |
16 | 16 | ||
17 | static void machine__remove_thread(struct machine *machine, struct thread *th); | ||
18 | |||
17 | static void dsos__init(struct dsos *dsos) | 19 | static void dsos__init(struct dsos *dsos) |
18 | { | 20 | { |
19 | INIT_LIST_HEAD(&dsos->head); | 21 | INIT_LIST_HEAD(&dsos->head); |
@@ -89,16 +91,6 @@ static void dsos__delete(struct dsos *dsos) | |||
89 | } | 91 | } |
90 | } | 92 | } |
91 | 93 | ||
92 | void machine__delete_dead_threads(struct machine *machine) | ||
93 | { | ||
94 | struct thread *n, *t; | ||
95 | |||
96 | list_for_each_entry_safe(t, n, &machine->dead_threads, node) { | ||
97 | list_del(&t->node); | ||
98 | thread__delete(t); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | void machine__delete_threads(struct machine *machine) | 94 | void machine__delete_threads(struct machine *machine) |
103 | { | 95 | { |
104 | struct rb_node *nd = rb_first(&machine->threads); | 96 | struct rb_node *nd = rb_first(&machine->threads); |
@@ -106,9 +98,8 @@ void machine__delete_threads(struct machine *machine) | |||
106 | while (nd) { | 98 | while (nd) { |
107 | struct thread *t = rb_entry(nd, struct thread, rb_node); | 99 | struct thread *t = rb_entry(nd, struct thread, rb_node); |
108 | 100 | ||
109 | rb_erase(&t->rb_node, &machine->threads); | ||
110 | nd = rb_next(nd); | 101 | nd = rb_next(nd); |
111 | thread__delete(t); | 102 | machine__remove_thread(machine, t); |
112 | } | 103 | } |
113 | } | 104 | } |
114 | 105 | ||
@@ -361,9 +352,13 @@ static struct thread *__machine__findnew_thread(struct machine *machine, | |||
361 | * the full rbtree: | 352 | * the full rbtree: |
362 | */ | 353 | */ |
363 | th = machine->last_match; | 354 | th = machine->last_match; |
364 | if (th && th->tid == tid) { | 355 | if (th != NULL) { |
365 | machine__update_thread_pid(machine, th, pid); | 356 | if (th->tid == tid) { |
366 | return th; | 357 | machine__update_thread_pid(machine, th, pid); |
358 | return th; | ||
359 | } | ||
360 | |||
361 | thread__zput(machine->last_match); | ||
367 | } | 362 | } |
368 | 363 | ||
369 | while (*p != NULL) { | 364 | while (*p != NULL) { |
@@ -371,7 +366,7 @@ static struct thread *__machine__findnew_thread(struct machine *machine, | |||
371 | th = rb_entry(parent, struct thread, rb_node); | 366 | th = rb_entry(parent, struct thread, rb_node); |
372 | 367 | ||
373 | if (th->tid == tid) { | 368 | if (th->tid == tid) { |
374 | machine->last_match = th; | 369 | machine->last_match = thread__get(th); |
375 | machine__update_thread_pid(machine, th, pid); | 370 | machine__update_thread_pid(machine, th, pid); |
376 | return th; | 371 | return th; |
377 | } | 372 | } |
@@ -403,8 +398,11 @@ static struct thread *__machine__findnew_thread(struct machine *machine, | |||
403 | thread__delete(th); | 398 | thread__delete(th); |
404 | return NULL; | 399 | return NULL; |
405 | } | 400 | } |
406 | 401 | /* | |
407 | machine->last_match = th; | 402 | * It is now in the rbtree, get a ref |
403 | */ | ||
404 | thread__get(th); | ||
405 | machine->last_match = thread__get(th); | ||
408 | } | 406 | } |
409 | 407 | ||
410 | return th; | 408 | return th; |
@@ -1238,13 +1236,17 @@ out_problem: | |||
1238 | 1236 | ||
1239 | static void machine__remove_thread(struct machine *machine, struct thread *th) | 1237 | static void machine__remove_thread(struct machine *machine, struct thread *th) |
1240 | { | 1238 | { |
1241 | machine->last_match = NULL; | 1239 | if (machine->last_match == th) |
1240 | thread__zput(machine->last_match); | ||
1241 | |||
1242 | rb_erase(&th->rb_node, &machine->threads); | 1242 | rb_erase(&th->rb_node, &machine->threads); |
1243 | /* | 1243 | /* |
1244 | * We may have references to this thread, for instance in some hist_entry | 1244 | * Move it first to the dead_threads list, then drop the reference, |
1245 | * instances, so just move them to a separate list. | 1245 | * if this is the last reference, then the thread__delete destructor |
1246 | * will be called and we will remove it from the dead_threads list. | ||
1246 | */ | 1247 | */ |
1247 | list_add_tail(&th->node, &machine->dead_threads); | 1248 | list_add_tail(&th->node, &machine->dead_threads); |
1249 | thread__put(th); | ||
1248 | } | 1250 | } |
1249 | 1251 | ||
1250 | int machine__process_fork_event(struct machine *machine, union perf_event *event, | 1252 | int machine__process_fork_event(struct machine *machine, union perf_event *event, |