perf tools: Add reference counting for thread_map object
authorJiri Olsa <jolsa@kernel.org>
Mon, 22 Jun 2015 22:36:05 +0000 (00:36 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 25 Jun 2015 18:15:50 +0000 (15:15 -0300)
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>
tools/perf/tests/code-reading.c
tools/perf/tests/keep-tracking.c
tools/perf/tests/mmap-basic.c
tools/perf/tests/mmap-thread-lookup.c
tools/perf/tests/openat-syscall-all-cpus.c
tools/perf/tests/openat-syscall.c
tools/perf/tests/switch-tracking.c
tools/perf/util/evlist.c
tools/perf/util/python.c
tools/perf/util/thread_map.c
tools/perf/util/thread_map.h

index 6b3250f542400ed76eacb169dff1841d7a260e55..39c784a100a955143e401fc46cbcb93a2a3d8136 100644 (file)
@@ -546,7 +546,7 @@ out_err:
                perf_evlist__delete(evlist);
        } else {
                cpu_map__put(cpus);
-               thread_map__delete(threads);
+               thread_map__put(threads);
        }
        machines__destroy_kernel_maps(&machines);
        machine__delete_threads(machine);
index a330235cefc0956df295c840c77c59bcf00dedfe..4d4b9837b630ae9fd72cb0a404a4bae0e3864e14 100644 (file)
@@ -145,7 +145,7 @@ out_err:
                perf_evlist__delete(evlist);
        } else {
                cpu_map__put(cpus);
-               thread_map__delete(threads);
+               thread_map__put(threads);
        }
 
        return err;
index 5a9ef5833452c4edcd9211d09ac828d3f70f62ed..666b67a4df9dd0d8ea8d41736af4355008c11464 100644 (file)
@@ -142,6 +142,6 @@ out_delete_evlist:
 out_free_cpus:
        cpu_map__put(cpus);
 out_free_threads:
-       thread_map__delete(threads);
+       thread_map__put(threads);
        return err;
 }
index 7f48efa7e295f63a72f0aa083857658ce68c45cb..145050e2e5446166f900f8d9405859b15bfcfff3 100644 (file)
@@ -143,7 +143,7 @@ static int synth_process(struct machine *machine)
                                                perf_event__process,
                                                machine, 0, 500);
 
-       thread_map__delete(map);
+       thread_map__put(map);
        return err;
 }
 
index 9a7a116e09b8087ef5f19e63113f6f65c1e0b5bf..b8d552b13950e98f2e1112dfa122303e1e7d3085 100644 (file)
@@ -111,6 +111,6 @@ out_close_fd:
 out_evsel_delete:
        perf_evsel__delete(evsel);
 out_thread_map_delete:
-       thread_map__delete(threads);
+       thread_map__put(threads);
        return err;
 }
index 9f9491bb8e4897faddcffed824b3d094f73b7d3d..bdfa1f446681eaffd6cb77da607da1dfbe839466 100644 (file)
@@ -56,6 +56,6 @@ out_close_fd:
 out_evsel_delete:
        perf_evsel__delete(evsel);
 out_thread_map_delete:
-       thread_map__delete(threads);
+       thread_map__put(threads);
        return err;
 }
index 1b06122beb76c165a1b80279ddc75abead6c8502..e698742d4fec3300ac6c6b00bf55696414567dd4 100644 (file)
@@ -561,7 +561,7 @@ out:
                perf_evlist__delete(evlist);
        } else {
                cpu_map__put(cpus);
-               thread_map__delete(threads);
+               thread_map__put(threads);
        }
 
        return err;
index 59498f7b3e9b0ac688f9ad0e539792944f2f6854..a8d18a3d216476412efc792e124bf0b3c628094a 100644 (file)
@@ -115,7 +115,7 @@ void perf_evlist__delete(struct perf_evlist *evlist)
        perf_evlist__munmap(evlist);
        perf_evlist__close(evlist);
        cpu_map__put(evlist->cpus);
-       thread_map__delete(evlist->threads);
+       thread_map__put(evlist->threads);
        evlist->cpus = NULL;
        evlist->threads = NULL;
        perf_evlist__purge(evlist);
@@ -1120,7 +1120,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
        return 0;
 
 out_delete_threads:
-       thread_map__delete(evlist->threads);
+       thread_map__put(evlist->threads);
        evlist->threads = NULL;
        return -1;
 }
index b106d56df24041c28e70deead7655278c71cdd5a..626422eda7274264c46ebca2aad48a51981788a2 100644 (file)
@@ -453,7 +453,7 @@ static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
 
 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
 {
-       thread_map__delete(pthreads->threads);
+       thread_map__put(pthreads->threads);
        pthreads->ob_type->tp_free((PyObject*)pthreads);
 }
 
index 920136dd8c2ec19d6c77e1f037d9582460a222d4..368cc58c6892c57200e79a4f3a0c380114f35f42 100644 (file)
@@ -8,6 +8,7 @@
 #include <unistd.h>
 #include "strlist.h"
 #include <string.h>
+#include "asm/bug.h"
 #include "thread_map.h"
 #include "util.h"
 
@@ -47,6 +48,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
                for (i = 0; i < items; i++)
                        thread_map__set_pid(threads, i, atoi(namelist[i]->d_name));
                threads->nr = items;
+               atomic_set(&threads->refcnt, 1);
        }
 
        for (i=0; i<items; i++)
@@ -63,6 +65,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
        if (threads != NULL) {
                thread_map__set_pid(threads, 0, tid);
                threads->nr = 1;
+               atomic_set(&threads->refcnt, 1);
        }
 
        return threads;
@@ -84,6 +87,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
                goto out_free_threads;
 
        threads->nr = 0;
+       atomic_set(&threads->refcnt, 1);
 
        while (!readdir_r(proc, &dirent, &next) && next) {
                char *end;
@@ -212,6 +216,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
 
 out:
        strlist__delete(slist);
+       if (threads)
+               atomic_set(&threads->refcnt, 1);
        return threads;
 
 out_free_namelist:
@@ -231,6 +237,7 @@ struct thread_map *thread_map__new_dummy(void)
        if (threads != NULL) {
                thread_map__set_pid(threads, 0, -1);
                threads->nr = 1;
+               atomic_set(&threads->refcnt, 1);
        }
        return threads;
 }
@@ -273,6 +280,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
                threads->nr = ntasks;
        }
 out:
+       if (threads)
+               atomic_set(&threads->refcnt, 1);
        return threads;
 
 out_free_threads:
@@ -292,9 +301,26 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid,
        return thread_map__new_by_tid_str(tid);
 }
 
-void thread_map__delete(struct thread_map *threads)
+static void thread_map__delete(struct thread_map *threads)
 {
-       free(threads);
+       if (threads) {
+               WARN_ONCE(atomic_read(&threads->refcnt) != 0,
+                         "thread map refcnt unbalanced\n");
+               free(threads);
+       }
+}
+
+struct thread_map *thread_map__get(struct thread_map *map)
+{
+       if (map)
+               atomic_inc(&map->refcnt);
+       return map;
+}
+
+void thread_map__put(struct thread_map *map)
+{
+       if (map && atomic_dec_and_test(&map->refcnt))
+               thread_map__delete(map);
 }
 
 size_t thread_map__fprintf(struct thread_map *threads, FILE *fp)
index b9f40679f589d5412742771c6975de5bcb0441f7..6b0cd2dc006b04e9f02ba851fdb547107f70fd70 100644 (file)
@@ -3,12 +3,14 @@
 
 #include <sys/types.h>
 #include <stdio.h>
+#include <linux/atomic.h>
 
 struct thread_map_data {
        pid_t    pid;
 };
 
 struct thread_map {
+       atomic_t refcnt;
        int nr;
        struct thread_map_data map[];
 };
@@ -19,11 +21,12 @@ struct thread_map *thread_map__new_by_tid(pid_t tid);
 struct thread_map *thread_map__new_by_uid(uid_t uid);
 struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid);
 
+struct thread_map *thread_map__get(struct thread_map *map);
+void thread_map__put(struct thread_map *map);
+
 struct thread_map *thread_map__new_str(const char *pid,
                const char *tid, uid_t uid);
 
-void thread_map__delete(struct thread_map *threads);
-
 size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
 
 static inline int thread_map__nr(struct thread_map *threads)
This page took 0.030536 seconds and 5 git commands to generate.