Messages in this thread | | | Date | Tue, 23 Jun 2015 18:01:58 -0300 | From | Arnaldo Carvalho de Melo <> | Subject | Re: [PATCH 02/27] perf tools: Add comm string into struct thread_map |
| |
Em Tue, Jun 23, 2015 at 12:36:03AM +0200, Jiri Olsa escreveu: > Adding support to hold comm name together with pids in > 'struct thread_map'. It will be useful for --per-thread > option to display task pid together with task name. > > Getting the task name from /proc/$pid/comm.
Do we really need to read this all the time? Or just for tools that need this?
Can't we have a thread_map__read_comms(map);
That we can make this specific --per-thread option in 'stat' call?
Applied the first patch after breaking it into two, one to add the accessors and the other to transform the map entries into a struct.
Pushed to perf/core already.
- Arnaldo
> Link: http://lkml.kernel.org/n/tip-pf6bgmbujukce0sgliuhj2f4@git.kernel.org > Signed-off-by: Jiri Olsa <jolsa@kernel.org> > --- > tools/perf/util/python-ext-sources | 1 + > tools/perf/util/thread_map.c | 67 ++++++++++++++++++++++++++++++++++++-- > tools/perf/util/thread_map.h | 12 +++++++ > 3 files changed, 77 insertions(+), 3 deletions(-) > > diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources > index 5925fec90562..e23ded40c79e 100644 > --- a/tools/perf/util/python-ext-sources > +++ b/tools/perf/util/python-ext-sources > @@ -20,3 +20,4 @@ util/stat.c > util/strlist.c > util/trace-event.c > ../../lib/rbtree.c > +util/string.c > diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c > index 7a4be3754d05..5b2f2495af26 100644 > --- a/tools/perf/util/thread_map.c > +++ b/tools/perf/util/thread_map.c > @@ -8,8 +8,10 @@ > #include <unistd.h> > #include "strlist.h" > #include <string.h> > +#include <api/fs/fs.h> > #include "thread_map.h" > #include "util.h" > +#include "debug.h" > > /* Skip "." and ".." directories */ > static int filter(const struct dirent *dir) > @@ -29,6 +31,51 @@ static struct thread_map *thread_map__realloc(struct thread_map *map, int nr) > > #define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr) > > +static int get_comm(char **comm, pid_t pid) > +{ > + char *path; > + size_t size; > + int err; > + > + if (asprintf(&path, "%s/%d/comm", procfs__mountpoint(), pid) == -1) > + return -ENOMEM; > + > + err = filename__read_str(path, comm, &size); > + if (!err) { > + /* > + * We're reading 16 bytes, while filename__read_str > + * allocates data per BUFSIZ bytes, so we can safely > + * mark the end of the string. > + */ > + (*comm)[size] = 0; > + rtrim(*comm); > + } > + > + free(path); > + return err; > +} > + > +static void comm_init(struct thread_map *map, int i) > +{ > + pid_t pid = thread_map__pid(map, i); > + char *comm = NULL; > + > + /* dummy pid comm initialization */ > + if (pid == -1) { > + thread_map__set_comm(map, i, strdup("dummy")); > + return; > + } > + > + /* > + * The comm name is like extra bonus ;-), > + * so just warn if we fail for any reason. > + */ > + if (get_comm(&comm, pid)) > + pr_warning("Couldn't resolve comm name for pid %d\n", pid); > + > + thread_map__set_comm(map, i, comm); > +} > + > struct thread_map *thread_map__new_by_pid(pid_t pid) > { > struct thread_map *threads; > @@ -44,8 +91,10 @@ struct thread_map *thread_map__new_by_pid(pid_t pid) > > threads = thread_map__alloc(items); > if (threads != NULL) { > - for (i = 0; i < items; i++) > + for (i = 0; i < items; i++) { > thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); > + comm_init(threads, i); > + } > threads->nr = items; > } > > @@ -63,6 +112,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; > + comm_init(threads, 0); > } > > return threads; > @@ -126,6 +176,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) > for (i = 0; i < items; i++) { > thread_map__set_pid(threads, threads->nr + i, > atoi(namelist[i]->d_name)); > + comm_init(threads, threads->nr + i); > } > > for (i = 0; i < items; i++) > @@ -202,8 +253,9 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) > > threads = nt; > > - for (i = 0; i < items; i++) { > - thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name)); > + for (i = 0; i < items; i++, j++) { > + thread_map__set_pid(threads, j, atoi(namelist[i]->d_name)); > + comm_init(threads, j); > zfree(&namelist[i]); > } > threads->nr = total_tasks; > @@ -231,6 +283,7 @@ struct thread_map *thread_map__new_dummy(void) > if (threads != NULL) { > thread_map__set_pid(threads, 0, -1); > threads->nr = 1; > + comm_init(threads, 0); > } > return threads; > } > @@ -271,6 +324,7 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) > threads = nt; > thread_map__set_pid(threads, ntasks - 1, tid); > threads->nr = ntasks; > + comm_init(threads, ntasks - 1); > } > out: > return threads; > @@ -294,6 +348,13 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid, > > void thread_map__delete(struct thread_map *threads) > { > + int i; > + > + if (threads) { > + for (i = 0; i < threads->nr; i++) > + free(thread_map__comm(threads, i)); > + } > + > free(threads); > } > > diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h > index b9f40679f589..0f67843475e6 100644 > --- a/tools/perf/util/thread_map.h > +++ b/tools/perf/util/thread_map.h > @@ -6,6 +6,7 @@ > > struct thread_map_data { > pid_t pid; > + char *comm; > }; > > struct thread_map { > @@ -41,4 +42,15 @@ thread_map__set_pid(struct thread_map *map, int thread, pid_t pid) > { > map->map[thread].pid = pid; > } > + > +static inline char *thread_map__comm(struct thread_map *map, int thread) > +{ > + return map->map[thread].comm; > +} > + > +static inline void > +thread_map__set_comm(struct thread_map *map, int thread, char *comm) > +{ > + map->map[thread].comm = comm; > +} > #endif /* __PERF_THREAD_MAP_H */ > -- > 1.9.3
| |