diff options
author | Jiri Olsa <jolsa@kernel.org> | 2015-06-26 05:29:07 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-06-26 10:07:01 -0400 |
commit | 792402fd5c0a5a5300868e9dfc8ee569f3a39169 (patch) | |
tree | ebb6df248a2b15b81b7fe8a0ac5e9f02a4ad6412 /tools | |
parent | 62eea464380633b88902da35bf9cbd8515289703 (diff) |
perf thrad_map: Add comm string into array
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.
Adding thread_map__read_comms function that reads/set
comm string for the 'struct thread_map'.
Getting the task name from /proc/$pid/comm.
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/1435310967-14570-3-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/python-ext-sources | 1 | ||||
-rw-r--r-- | tools/perf/util/thread_map.c | 59 | ||||
-rw-r--r-- | tools/perf/util/thread_map.h | 8 |
3 files changed, 68 insertions, 0 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 | |||
20 | util/strlist.c | 20 | util/strlist.c |
21 | util/trace-event.c | 21 | util/trace-event.c |
22 | ../../lib/rbtree.c | 22 | ../../lib/rbtree.c |
23 | util/string.c | ||
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index ed76c179cf4e..da7646d767fe 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c | |||
@@ -8,9 +8,11 @@ | |||
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 <api/fs/fs.h> | ||
11 | #include "asm/bug.h" | 12 | #include "asm/bug.h" |
12 | #include "thread_map.h" | 13 | #include "thread_map.h" |
13 | #include "util.h" | 14 | #include "util.h" |
15 | #include "debug.h" | ||
14 | 16 | ||
15 | /* Skip "." and ".." directories */ | 17 | /* Skip "." and ".." directories */ |
16 | static int filter(const struct dirent *dir) | 18 | static int filter(const struct dirent *dir) |
@@ -319,8 +321,12 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid, | |||
319 | static void thread_map__delete(struct thread_map *threads) | 321 | static void thread_map__delete(struct thread_map *threads) |
320 | { | 322 | { |
321 | if (threads) { | 323 | if (threads) { |
324 | int i; | ||
325 | |||
322 | WARN_ONCE(atomic_read(&threads->refcnt) != 0, | 326 | WARN_ONCE(atomic_read(&threads->refcnt) != 0, |
323 | "thread map refcnt unbalanced\n"); | 327 | "thread map refcnt unbalanced\n"); |
328 | for (i = 0; i < threads->nr; i++) | ||
329 | free(thread_map__comm(threads, i)); | ||
324 | free(threads); | 330 | free(threads); |
325 | } | 331 | } |
326 | } | 332 | } |
@@ -348,3 +354,56 @@ size_t thread_map__fprintf(struct thread_map *threads, FILE *fp) | |||
348 | 354 | ||
349 | return printed + fprintf(fp, "\n"); | 355 | return printed + fprintf(fp, "\n"); |
350 | } | 356 | } |
357 | |||
358 | static int get_comm(char **comm, pid_t pid) | ||
359 | { | ||
360 | char *path; | ||
361 | size_t size; | ||
362 | int err; | ||
363 | |||
364 | if (asprintf(&path, "%s/%d/comm", procfs__mountpoint(), pid) == -1) | ||
365 | return -ENOMEM; | ||
366 | |||
367 | err = filename__read_str(path, comm, &size); | ||
368 | if (!err) { | ||
369 | /* | ||
370 | * We're reading 16 bytes, while filename__read_str | ||
371 | * allocates data per BUFSIZ bytes, so we can safely | ||
372 | * mark the end of the string. | ||
373 | */ | ||
374 | (*comm)[size] = 0; | ||
375 | rtrim(*comm); | ||
376 | } | ||
377 | |||
378 | free(path); | ||
379 | return err; | ||
380 | } | ||
381 | |||
382 | static void comm_init(struct thread_map *map, int i) | ||
383 | { | ||
384 | pid_t pid = thread_map__pid(map, i); | ||
385 | char *comm = NULL; | ||
386 | |||
387 | /* dummy pid comm initialization */ | ||
388 | if (pid == -1) { | ||
389 | map->map[i].comm = strdup("dummy"); | ||
390 | return; | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * The comm name is like extra bonus ;-), | ||
395 | * so just warn if we fail for any reason. | ||
396 | */ | ||
397 | if (get_comm(&comm, pid)) | ||
398 | pr_warning("Couldn't resolve comm name for pid %d\n", pid); | ||
399 | |||
400 | map->map[i].comm = comm; | ||
401 | } | ||
402 | |||
403 | void thread_map__read_comms(struct thread_map *threads) | ||
404 | { | ||
405 | int i; | ||
406 | |||
407 | for (i = 0; i < threads->nr; ++i) | ||
408 | comm_init(threads, i); | ||
409 | } | ||
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 6b0cd2dc006b..af679d8a50f8 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | struct thread_map_data { | 8 | struct thread_map_data { |
9 | pid_t pid; | 9 | pid_t pid; |
10 | char *comm; | ||
10 | }; | 11 | }; |
11 | 12 | ||
12 | struct thread_map { | 13 | struct thread_map { |
@@ -44,4 +45,11 @@ thread_map__set_pid(struct thread_map *map, int thread, pid_t pid) | |||
44 | { | 45 | { |
45 | map->map[thread].pid = pid; | 46 | map->map[thread].pid = pid; |
46 | } | 47 | } |
48 | |||
49 | static inline char *thread_map__comm(struct thread_map *map, int thread) | ||
50 | { | ||
51 | return map->map[thread].comm; | ||
52 | } | ||
53 | |||
54 | void thread_map__read_comms(struct thread_map *threads); | ||
47 | #endif /* __PERF_THREAD_MAP_H */ | 55 | #endif /* __PERF_THREAD_MAP_H */ |