Commit 186fbb74 authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo

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: default avatarJiri 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f30a79b0
...@@ -546,7 +546,7 @@ static int do_test_code_reading(bool try_kcore) ...@@ -546,7 +546,7 @@ static int do_test_code_reading(bool try_kcore)
perf_evlist__delete(evlist); perf_evlist__delete(evlist);
} else { } else {
cpu_map__put(cpus); cpu_map__put(cpus);
thread_map__delete(threads); thread_map__put(threads);
} }
machines__destroy_kernel_maps(&machines); machines__destroy_kernel_maps(&machines);
machine__delete_threads(machine); machine__delete_threads(machine);
......
...@@ -145,7 +145,7 @@ int test__keep_tracking(void) ...@@ -145,7 +145,7 @@ int test__keep_tracking(void)
perf_evlist__delete(evlist); perf_evlist__delete(evlist);
} else { } else {
cpu_map__put(cpus); cpu_map__put(cpus);
thread_map__delete(threads); thread_map__put(threads);
} }
return err; return err;
......
...@@ -142,6 +142,6 @@ int test__basic_mmap(void) ...@@ -142,6 +142,6 @@ int test__basic_mmap(void)
out_free_cpus: out_free_cpus:
cpu_map__put(cpus); cpu_map__put(cpus);
out_free_threads: out_free_threads:
thread_map__delete(threads); thread_map__put(threads);
return err; return err;
} }
...@@ -143,7 +143,7 @@ static int synth_process(struct machine *machine) ...@@ -143,7 +143,7 @@ static int synth_process(struct machine *machine)
perf_event__process, perf_event__process,
machine, 0, 500); machine, 0, 500);
thread_map__delete(map); thread_map__put(map);
return err; return err;
} }
......
...@@ -111,6 +111,6 @@ int test__openat_syscall_event_on_all_cpus(void) ...@@ -111,6 +111,6 @@ int test__openat_syscall_event_on_all_cpus(void)
out_evsel_delete: out_evsel_delete:
perf_evsel__delete(evsel); perf_evsel__delete(evsel);
out_thread_map_delete: out_thread_map_delete:
thread_map__delete(threads); thread_map__put(threads);
return err; return err;
} }
...@@ -56,6 +56,6 @@ int test__openat_syscall_event(void) ...@@ -56,6 +56,6 @@ int test__openat_syscall_event(void)
out_evsel_delete: out_evsel_delete:
perf_evsel__delete(evsel); perf_evsel__delete(evsel);
out_thread_map_delete: out_thread_map_delete:
thread_map__delete(threads); thread_map__put(threads);
return err; return err;
} }
...@@ -561,7 +561,7 @@ int test__switch_tracking(void) ...@@ -561,7 +561,7 @@ int test__switch_tracking(void)
perf_evlist__delete(evlist); perf_evlist__delete(evlist);
} else { } else {
cpu_map__put(cpus); cpu_map__put(cpus);
thread_map__delete(threads); thread_map__put(threads);
} }
return err; return err;
......
...@@ -115,7 +115,7 @@ void perf_evlist__delete(struct perf_evlist *evlist) ...@@ -115,7 +115,7 @@ void perf_evlist__delete(struct perf_evlist *evlist)
perf_evlist__munmap(evlist); perf_evlist__munmap(evlist);
perf_evlist__close(evlist); perf_evlist__close(evlist);
cpu_map__put(evlist->cpus); cpu_map__put(evlist->cpus);
thread_map__delete(evlist->threads); thread_map__put(evlist->threads);
evlist->cpus = NULL; evlist->cpus = NULL;
evlist->threads = NULL; evlist->threads = NULL;
perf_evlist__purge(evlist); perf_evlist__purge(evlist);
...@@ -1120,7 +1120,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) ...@@ -1120,7 +1120,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
return 0; return 0;
out_delete_threads: out_delete_threads:
thread_map__delete(evlist->threads); thread_map__put(evlist->threads);
evlist->threads = NULL; evlist->threads = NULL;
return -1; return -1;
} }
......
...@@ -453,7 +453,7 @@ static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, ...@@ -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) 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); pthreads->ob_type->tp_free((PyObject*)pthreads);
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <unistd.h> #include <unistd.h>
#include "strlist.h" #include "strlist.h"
#include <string.h> #include <string.h>
#include "asm/bug.h"
#include "thread_map.h" #include "thread_map.h"
#include "util.h" #include "util.h"
...@@ -47,6 +48,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid) ...@@ -47,6 +48,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
for (i = 0; i < items; i++) for (i = 0; i < items; i++)
thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); thread_map__set_pid(threads, i, atoi(namelist[i]->d_name));
threads->nr = items; threads->nr = items;
atomic_set(&threads->refcnt, 1);
} }
for (i=0; i<items; i++) for (i=0; i<items; i++)
...@@ -63,6 +65,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid) ...@@ -63,6 +65,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
if (threads != NULL) { if (threads != NULL) {
thread_map__set_pid(threads, 0, tid); thread_map__set_pid(threads, 0, tid);
threads->nr = 1; threads->nr = 1;
atomic_set(&threads->refcnt, 1);
} }
return threads; return threads;
...@@ -84,6 +87,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) ...@@ -84,6 +87,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
goto out_free_threads; goto out_free_threads;
threads->nr = 0; threads->nr = 0;
atomic_set(&threads->refcnt, 1);
while (!readdir_r(proc, &dirent, &next) && next) { while (!readdir_r(proc, &dirent, &next) && next) {
char *end; char *end;
...@@ -212,6 +216,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) ...@@ -212,6 +216,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
out: out:
strlist__delete(slist); strlist__delete(slist);
if (threads)
atomic_set(&threads->refcnt, 1);
return threads; return threads;
out_free_namelist: out_free_namelist:
...@@ -231,6 +237,7 @@ struct thread_map *thread_map__new_dummy(void) ...@@ -231,6 +237,7 @@ struct thread_map *thread_map__new_dummy(void)
if (threads != NULL) { if (threads != NULL) {
thread_map__set_pid(threads, 0, -1); thread_map__set_pid(threads, 0, -1);
threads->nr = 1; threads->nr = 1;
atomic_set(&threads->refcnt, 1);
} }
return threads; return threads;
} }
...@@ -273,6 +280,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) ...@@ -273,6 +280,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
threads->nr = ntasks; threads->nr = ntasks;
} }
out: out:
if (threads)
atomic_set(&threads->refcnt, 1);
return threads; return threads;
out_free_threads: out_free_threads:
...@@ -292,9 +301,26 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid, ...@@ -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); 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) size_t thread_map__fprintf(struct thread_map *threads, FILE *fp)
......
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <linux/atomic.h>
struct thread_map_data { struct thread_map_data {
pid_t pid; pid_t pid;
}; };
struct thread_map { struct thread_map {
atomic_t refcnt;
int nr; int nr;
struct thread_map_data map[]; struct thread_map_data map[];
}; };
...@@ -19,11 +21,12 @@ struct thread_map *thread_map__new_by_tid(pid_t tid); ...@@ -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_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__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, struct thread_map *thread_map__new_str(const char *pid,
const char *tid, uid_t uid); 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); size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
static inline int thread_map__nr(struct thread_map *threads) static inline int thread_map__nr(struct thread_map *threads)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment