aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2015-06-22 18:36:05 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-06-25 14:15:50 -0400
commit186fbb7432f4a740b4fbaf4145375442210110bb (patch)
treedbe98386a183e60d849c11f12c1396abd4baa05e
parentf30a79b012e5d9b3887f6a59293d9ef3ca0e2c3e (diff)
perf tools: Add reference counting for thread_map object
Adding reference counting for thread_map object, so it could be easily shared among other objects. Using thread_map__put instead thread_map__delete and making thread_map__delete static. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1435012588-9007-5-git-send-email-jolsa@kernel.org [ Adjustments to move it ahead of the "comm" patches ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/tests/code-reading.c2
-rw-r--r--tools/perf/tests/keep-tracking.c2
-rw-r--r--tools/perf/tests/mmap-basic.c2
-rw-r--r--tools/perf/tests/mmap-thread-lookup.c2
-rw-r--r--tools/perf/tests/openat-syscall-all-cpus.c2
-rw-r--r--tools/perf/tests/openat-syscall.c2
-rw-r--r--tools/perf/tests/switch-tracking.c2
-rw-r--r--tools/perf/util/evlist.c4
-rw-r--r--tools/perf/util/python.c2
-rw-r--r--tools/perf/util/thread_map.c30
-rw-r--r--tools/perf/util/thread_map.h7
11 files changed, 43 insertions, 14 deletions
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 6b3250f54240..39c784a100a9 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -546,7 +546,7 @@ out_err:
546 perf_evlist__delete(evlist); 546 perf_evlist__delete(evlist);
547 } else { 547 } else {
548 cpu_map__put(cpus); 548 cpu_map__put(cpus);
549 thread_map__delete(threads); 549 thread_map__put(threads);
550 } 550 }
551 machines__destroy_kernel_maps(&machines); 551 machines__destroy_kernel_maps(&machines);
552 machine__delete_threads(machine); 552 machine__delete_threads(machine);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index a330235cefc0..4d4b9837b630 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -145,7 +145,7 @@ out_err:
145 perf_evlist__delete(evlist); 145 perf_evlist__delete(evlist);
146 } else { 146 } else {
147 cpu_map__put(cpus); 147 cpu_map__put(cpus);
148 thread_map__delete(threads); 148 thread_map__put(threads);
149 } 149 }
150 150
151 return err; 151 return err;
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 5a9ef5833452..666b67a4df9d 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -142,6 +142,6 @@ out_delete_evlist:
142out_free_cpus: 142out_free_cpus:
143 cpu_map__put(cpus); 143 cpu_map__put(cpus);
144out_free_threads: 144out_free_threads:
145 thread_map__delete(threads); 145 thread_map__put(threads);
146 return err; 146 return err;
147} 147}
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index 7f48efa7e295..145050e2e544 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -143,7 +143,7 @@ static int synth_process(struct machine *machine)
143 perf_event__process, 143 perf_event__process,
144 machine, 0, 500); 144 machine, 0, 500);
145 145
146 thread_map__delete(map); 146 thread_map__put(map);
147 return err; 147 return err;
148} 148}
149 149
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 9a7a116e09b8..b8d552b13950 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -111,6 +111,6 @@ out_close_fd:
111out_evsel_delete: 111out_evsel_delete:
112 perf_evsel__delete(evsel); 112 perf_evsel__delete(evsel);
113out_thread_map_delete: 113out_thread_map_delete:
114 thread_map__delete(threads); 114 thread_map__put(threads);
115 return err; 115 return err;
116} 116}
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index 9f9491bb8e48..bdfa1f446681 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -56,6 +56,6 @@ out_close_fd:
56out_evsel_delete: 56out_evsel_delete:
57 perf_evsel__delete(evsel); 57 perf_evsel__delete(evsel);
58out_thread_map_delete: 58out_thread_map_delete:
59 thread_map__delete(threads); 59 thread_map__put(threads);
60 return err; 60 return err;
61} 61}
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 1b06122beb76..e698742d4fec 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -561,7 +561,7 @@ out:
561 perf_evlist__delete(evlist); 561 perf_evlist__delete(evlist);
562 } else { 562 } else {
563 cpu_map__put(cpus); 563 cpu_map__put(cpus);
564 thread_map__delete(threads); 564 thread_map__put(threads);
565 } 565 }
566 566
567 return err; 567 return err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 59498f7b3e9b..a8d18a3d2164 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -115,7 +115,7 @@ void perf_evlist__delete(struct perf_evlist *evlist)
115 perf_evlist__munmap(evlist); 115 perf_evlist__munmap(evlist);
116 perf_evlist__close(evlist); 116 perf_evlist__close(evlist);
117 cpu_map__put(evlist->cpus); 117 cpu_map__put(evlist->cpus);
118 thread_map__delete(evlist->threads); 118 thread_map__put(evlist->threads);
119 evlist->cpus = NULL; 119 evlist->cpus = NULL;
120 evlist->threads = NULL; 120 evlist->threads = NULL;
121 perf_evlist__purge(evlist); 121 perf_evlist__purge(evlist);
@@ -1120,7 +1120,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
1120 return 0; 1120 return 0;
1121 1121
1122out_delete_threads: 1122out_delete_threads:
1123 thread_map__delete(evlist->threads); 1123 thread_map__put(evlist->threads);
1124 evlist->threads = NULL; 1124 evlist->threads = NULL;
1125 return -1; 1125 return -1;
1126} 1126}
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index b106d56df240..626422eda727 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -453,7 +453,7 @@ static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
453 453
454static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads) 454static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
455{ 455{
456 thread_map__delete(pthreads->threads); 456 thread_map__put(pthreads->threads);
457 pthreads->ob_type->tp_free((PyObject*)pthreads); 457 pthreads->ob_type->tp_free((PyObject*)pthreads);
458} 458}
459 459
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 920136dd8c2e..368cc58c6892 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -8,6 +8,7 @@
8#include <unistd.h> 8#include <unistd.h>
9#include "strlist.h" 9#include "strlist.h"
10#include <string.h> 10#include <string.h>
11#include "asm/bug.h"
11#include "thread_map.h" 12#include "thread_map.h"
12#include "util.h" 13#include "util.h"
13 14
@@ -47,6 +48,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
47 for (i = 0; i < items; i++) 48 for (i = 0; i < items; i++)
48 thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); 49 thread_map__set_pid(threads, i, atoi(namelist[i]->d_name));
49 threads->nr = items; 50 threads->nr = items;
51 atomic_set(&threads->refcnt, 1);
50 } 52 }
51 53
52 for (i=0; i<items; i++) 54 for (i=0; i<items; i++)
@@ -63,6 +65,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
63 if (threads != NULL) { 65 if (threads != NULL) {
64 thread_map__set_pid(threads, 0, tid); 66 thread_map__set_pid(threads, 0, tid);
65 threads->nr = 1; 67 threads->nr = 1;
68 atomic_set(&threads->refcnt, 1);
66 } 69 }
67 70
68 return threads; 71 return threads;
@@ -84,6 +87,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
84 goto out_free_threads; 87 goto out_free_threads;
85 88
86 threads->nr = 0; 89 threads->nr = 0;
90 atomic_set(&threads->refcnt, 1);
87 91
88 while (!readdir_r(proc, &dirent, &next) && next) { 92 while (!readdir_r(proc, &dirent, &next) && next) {
89 char *end; 93 char *end;
@@ -212,6 +216,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
212 216
213out: 217out:
214 strlist__delete(slist); 218 strlist__delete(slist);
219 if (threads)
220 atomic_set(&threads->refcnt, 1);
215 return threads; 221 return threads;
216 222
217out_free_namelist: 223out_free_namelist:
@@ -231,6 +237,7 @@ struct thread_map *thread_map__new_dummy(void)
231 if (threads != NULL) { 237 if (threads != NULL) {
232 thread_map__set_pid(threads, 0, -1); 238 thread_map__set_pid(threads, 0, -1);
233 threads->nr = 1; 239 threads->nr = 1;
240 atomic_set(&threads->refcnt, 1);
234 } 241 }
235 return threads; 242 return threads;
236} 243}
@@ -273,6 +280,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
273 threads->nr = ntasks; 280 threads->nr = ntasks;
274 } 281 }
275out: 282out:
283 if (threads)
284 atomic_set(&threads->refcnt, 1);
276 return threads; 285 return threads;
277 286
278out_free_threads: 287out_free_threads:
@@ -292,9 +301,26 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid,
292 return thread_map__new_by_tid_str(tid); 301 return thread_map__new_by_tid_str(tid);
293} 302}
294 303
295void thread_map__delete(struct thread_map *threads) 304static void thread_map__delete(struct thread_map *threads)
296{ 305{
297 free(threads); 306 if (threads) {
307 WARN_ONCE(atomic_read(&threads->refcnt) != 0,
308 "thread map refcnt unbalanced\n");
309 free(threads);
310 }
311}
312
313struct thread_map *thread_map__get(struct thread_map *map)
314{
315 if (map)
316 atomic_inc(&map->refcnt);
317 return map;
318}
319
320void thread_map__put(struct thread_map *map)
321{
322 if (map && atomic_dec_and_test(&map->refcnt))
323 thread_map__delete(map);
298} 324}
299 325
300size_t thread_map__fprintf(struct thread_map *threads, FILE *fp) 326size_t thread_map__fprintf(struct thread_map *threads, FILE *fp)
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index b9f40679f589..6b0cd2dc006b 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -3,12 +3,14 @@
3 3
4#include <sys/types.h> 4#include <sys/types.h>
5#include <stdio.h> 5#include <stdio.h>
6#include <linux/atomic.h>
6 7
7struct thread_map_data { 8struct thread_map_data {
8 pid_t pid; 9 pid_t pid;
9}; 10};
10 11
11struct thread_map { 12struct thread_map {
13 atomic_t refcnt;
12 int nr; 14 int nr;
13 struct thread_map_data map[]; 15 struct thread_map_data map[];
14}; 16};
@@ -19,11 +21,12 @@ struct thread_map *thread_map__new_by_tid(pid_t tid);
19struct thread_map *thread_map__new_by_uid(uid_t uid); 21struct thread_map *thread_map__new_by_uid(uid_t uid);
20struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid); 22struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid);
21 23
24struct thread_map *thread_map__get(struct thread_map *map);
25void thread_map__put(struct thread_map *map);
26
22struct thread_map *thread_map__new_str(const char *pid, 27struct thread_map *thread_map__new_str(const char *pid,
23 const char *tid, uid_t uid); 28 const char *tid, uid_t uid);
24 29
25void thread_map__delete(struct thread_map *threads);
26
27size_t thread_map__fprintf(struct thread_map *threads, FILE *fp); 30size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
28 31
29static inline int thread_map__nr(struct thread_map *threads) 32static inline int thread_map__nr(struct thread_map *threads)