aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2015-03-30 16:35:57 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-03-31 16:52:30 -0400
commit5aa0b030e8d29d6719c144818814b519cfcb105c (patch)
tree5558b3d391b99c78f2fe3003499815883a7536ba /tools/perf
parent73dbcd6537f0ef6bf98d84f8fd7f8ab9994c6cd8 (diff)
perf tools: Refactor comm/tgid lookup
Rather than parsing /proc/pid/status file one line at a time, read it into a buffer in one shot and search for all strings in one pass. tgid conversion also simplified -- removing the isspace walk. As noted by Arnaldo those are not needed for atoi == strtol calls. Signed-off-by: David Ahern <dsahern@gmail.com> Acked-by: Don Zickus <dzickus@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Joe Mario <jmario@redhat.com> Link: http://lkml.kernel.org/r/1427747758-18510-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/event.c72
1 files changed, 44 insertions, 28 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d5efa5092ce6..023dd3548a94 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -49,48 +49,64 @@ static struct perf_sample synth_sample = {
49 .period = 1, 49 .period = 1,
50}; 50};
51 51
52/*
53 * Assumes that the first 4095 bytes of /proc/pid/stat contains
54 * the comm and tgid.
55 */
52static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) 56static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len)
53{ 57{
54 char filename[PATH_MAX]; 58 char filename[PATH_MAX];
55 char bf[BUFSIZ]; 59 char bf[4096];
56 FILE *fp; 60 int fd;
57 size_t size = 0; 61 size_t size = 0, n;
58 pid_t tgid = -1; 62 pid_t tgid = -1;
63 char *nl, *name, *tgids;
59 64
60 snprintf(filename, sizeof(filename), "/proc/%d/status", pid); 65 snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
61 66
62 fp = fopen(filename, "r"); 67 fd = open(filename, O_RDONLY);
63 if (fp == NULL) { 68 if (fd < 0) {
64 pr_debug("couldn't open %s\n", filename); 69 pr_debug("couldn't open %s\n", filename);
65 return 0; 70 return 0;
66 } 71 }
67 72
68 while (!comm[0] || (tgid < 0)) { 73 n = read(fd, bf, sizeof(bf) - 1);
69 if (fgets(bf, sizeof(bf), fp) == NULL) { 74 close(fd);
70 pr_warning("couldn't get COMM and pgid, malformed %s\n", 75 if (n <= 0) {
71 filename); 76 pr_warning("Couldn't get COMM and tgid for pid %d\n",
72 break; 77 pid);
73 } 78 return -1;
79 }
80 bf[n] = '\0';
74 81
75 if (memcmp(bf, "Name:", 5) == 0) { 82 name = strstr(bf, "Name:");
76 char *name = bf + 5; 83 tgids = strstr(bf, "Tgid:");
77 while (*name && isspace(*name)) 84
78 ++name; 85 if (name) {
79 size = strlen(name) - 1; 86 name += 5; /* strlen("Name:") */
80 if (size >= len) 87
81 size = len - 1; 88 while (*name && isspace(*name))
82 memcpy(comm, name, size); 89 ++name;
83 comm[size] = '\0'; 90
84 91 nl = strchr(name, '\n');
85 } else if (memcmp(bf, "Tgid:", 5) == 0) { 92 if (nl)
86 char *tgids = bf + 5; 93 *nl = '\0';
87 while (*tgids && isspace(*tgids)) 94
88 ++tgids; 95 size = strlen(name);
89 tgid = atoi(tgids); 96 if (size >= len)
90 } 97 size = len - 1;
98 memcpy(comm, name, size);
99 comm[size] = '\0';
100 } else {
101 pr_debug("Name: string not found for pid %d\n", pid);
91 } 102 }
92 103
93 fclose(fp); 104 if (tgids) {
105 tgids += 5; /* strlen("Tgid:") */
106 tgid = atoi(tgids);
107 } else {
108 pr_debug("Tgid: string not found for pid %d\n", pid);
109 }
94 110
95 return tgid; 111 return tgid;
96} 112}