diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-04-07 10:59:50 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-05-08 15:16:23 -0400 |
commit | e1ed3a5b87ed6759e16ec93f16aae83d2cc77ca2 (patch) | |
tree | 5eb80c8b87ad735bca3f9ce50751da06f8b63f1e | |
parent | da6d8567512df11e0473b710c07de87efde5709c (diff) |
perf tools: Use atomic_t to implement thread__{get,put} refcnt
Fixing bugs in 'perf top' where the used thread unsafe 'struct thread'
refcount implementation was falling apart because we really use two
threads.
Acked-by: David Ahern <dsahern@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-hil2hol294u5ntcuof4jhmn6@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/thread.c | 6 | ||||
-rw-r--r-- | tools/perf/util/thread.h | 3 |
2 files changed, 5 insertions, 4 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 1c8fbc9588c5..1b265521836c 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -53,7 +53,7 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
53 | goto err_thread; | 53 | goto err_thread; |
54 | 54 | ||
55 | list_add(&comm->list, &thread->comm_list); | 55 | list_add(&comm->list, &thread->comm_list); |
56 | 56 | atomic_set(&thread->refcnt, 0); | |
57 | } | 57 | } |
58 | 58 | ||
59 | return thread; | 59 | return thread; |
@@ -84,13 +84,13 @@ void thread__delete(struct thread *thread) | |||
84 | 84 | ||
85 | struct thread *thread__get(struct thread *thread) | 85 | struct thread *thread__get(struct thread *thread) |
86 | { | 86 | { |
87 | ++thread->refcnt; | 87 | atomic_inc(&thread->refcnt); |
88 | return thread; | 88 | return thread; |
89 | } | 89 | } |
90 | 90 | ||
91 | void thread__put(struct thread *thread) | 91 | void thread__put(struct thread *thread) |
92 | { | 92 | { |
93 | if (thread && --thread->refcnt == 0) { | 93 | if (thread && atomic_dec_and_test(&thread->refcnt)) { |
94 | list_del_init(&thread->node); | 94 | list_del_init(&thread->node); |
95 | thread__delete(thread); | 95 | thread__delete(thread); |
96 | } | 96 | } |
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 9b8a54dc34a8..f33c48cfdaa0 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __PERF_THREAD_H | 1 | #ifndef __PERF_THREAD_H |
2 | #define __PERF_THREAD_H | 2 | #define __PERF_THREAD_H |
3 | 3 | ||
4 | #include <linux/atomic.h> | ||
4 | #include <linux/rbtree.h> | 5 | #include <linux/rbtree.h> |
5 | #include <linux/list.h> | 6 | #include <linux/list.h> |
6 | #include <unistd.h> | 7 | #include <unistd.h> |
@@ -21,7 +22,7 @@ struct thread { | |||
21 | pid_t tid; | 22 | pid_t tid; |
22 | pid_t ppid; | 23 | pid_t ppid; |
23 | int cpu; | 24 | int cpu; |
24 | int refcnt; | 25 | atomic_t refcnt; |
25 | char shortname[3]; | 26 | char shortname[3]; |
26 | bool comm_set; | 27 | bool comm_set; |
27 | bool dead; /* if set thread has exited */ | 28 | bool dead; /* if set thread has exited */ |