Adding support to hold comm name together with pids in 'struct thread_map'. It will be useful for --per-task option to display task pid together with task name.
Getting the task name from /proc/$pid/comm. Link: http://lkml.kernel.org/n/tip-pf6bgmbujukce0sgliuhj...@git.kernel.org Signed-off-by: Jiri Olsa <jo...@kernel.org> --- tools/perf/util/python-ext-sources | 1 + tools/perf/util/thread_map.c | 63 +++++++++++++++++++++++++++++++++++--- tools/perf/util/thread_map.h | 2 ++ 3 files changed, 62 insertions(+), 4 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 7f03f9facfdd..f7a49a693d27 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,44 @@ 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) + rtrim(*comm); + + free(path); + return err; +} + +static void comm_init(struct thread_map *map, int i) +{ + struct thread_map_data *data = &map->map[i]; + + /* + * The comm name is like extra bonus ;-), + * so just warn if we fail for any reason. + */ + data->comm = NULL; + + /* dummy pid comm initialization */ + if (data->pid == -1) { + data->comm = strdup("dummy"); + return; + } + + /* try to get pid's comm string */ + if (get_comm(&data->comm, data->pid)) + pr_warning("Couldn't resolve comm name for pid %d\n", data->pid); +} + struct thread_map *thread_map__new_by_pid(pid_t pid) { struct thread_map *threads; @@ -44,8 +84,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__pid(threads, i) = atoi(namelist[i]->d_name); + comm_init(threads, i); + } threads->nr = items; } @@ -63,6 +105,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid) if (threads != NULL) { thread_map__pid(threads, 0) = tid; threads->nr = 1; + comm_init(threads, 0); } return threads; @@ -123,8 +166,10 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) threads = tmp; } - for (i = 0; i < items; i++) + for (i = 0; i < items; i++) { thread_map__pid(threads, threads->nr + i) = atoi(namelist[i]->d_name); + comm_init(threads, threads->nr + i); + } for (i = 0; i < items; i++) zfree(&namelist[i]); @@ -200,8 +245,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__pid(threads, j++) = atoi(namelist[i]->d_name); + for (i = 0; i < items; i++, j++) { + thread_map__pid(threads, j) = atoi(namelist[i]->d_name); + comm_init(threads, j); zfree(&namelist[i]); } threads->nr = total_tasks; @@ -229,6 +275,7 @@ struct thread_map *thread_map__new_dummy(void) if (threads != NULL) { thread_map__pid(threads, 0) = -1; threads->nr = 1; + comm_init(threads, 0); } return threads; } @@ -269,6 +316,7 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) threads = nt; thread_map__pid(threads, ntasks - 1) = tid; threads->nr = ntasks; + comm_init(threads, ntasks - 1); } out: return threads; @@ -292,6 +340,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 9377850c7b71..6933f9d316d9 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 { @@ -14,6 +15,7 @@ struct thread_map { }; #define thread_map__pid(__m, __t) __m->map[__t].pid +#define thread_map__comm(__m, __t) __m->map[__t].comm struct thread_map *thread_map__new_dummy(void); struct thread_map *thread_map__new_by_pid(pid_t pid); -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/