diff options
-rw-r--r-- | Documentation/perf_counter/builtin-stat.c | 116 |
1 files changed, 67 insertions, 49 deletions
diff --git a/Documentation/perf_counter/builtin-stat.c b/Documentation/perf_counter/builtin-stat.c index ac14086d9a70..6a2936150f28 100644 --- a/Documentation/perf_counter/builtin-stat.c +++ b/Documentation/perf_counter/builtin-stat.c | |||
@@ -109,11 +109,75 @@ static void create_perfstat_counter(int counter) | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | /* | ||
113 | * Does the counter have nsecs as a unit? | ||
114 | */ | ||
115 | static inline int nsec_counter(int counter) | ||
116 | { | ||
117 | if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK)) | ||
118 | return 1; | ||
119 | if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) | ||
120 | return 1; | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Print out the results of a single counter: | ||
127 | */ | ||
128 | static void print_counter(int counter) | ||
129 | { | ||
130 | __u64 count[3], single_count[3]; | ||
131 | ssize_t res; | ||
132 | int cpu, nv; | ||
133 | int scaled; | ||
134 | |||
135 | count[0] = count[1] = count[2] = 0; | ||
136 | nv = scale ? 3 : 1; | ||
137 | for (cpu = 0; cpu < nr_cpus; cpu ++) { | ||
138 | res = read(fd[cpu][counter], single_count, nv * sizeof(__u64)); | ||
139 | assert(res == nv * sizeof(__u64)); | ||
140 | |||
141 | count[0] += single_count[0]; | ||
142 | if (scale) { | ||
143 | count[1] += single_count[1]; | ||
144 | count[2] += single_count[2]; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | scaled = 0; | ||
149 | if (scale) { | ||
150 | if (count[2] == 0) { | ||
151 | fprintf(stderr, " %14s %-20s\n", | ||
152 | "<not counted>", event_name(counter)); | ||
153 | return; | ||
154 | } | ||
155 | if (count[2] < count[1]) { | ||
156 | scaled = 1; | ||
157 | count[0] = (unsigned long long) | ||
158 | ((double)count[0] * count[1] / count[2] + 0.5); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | if (nsec_counter(counter)) { | ||
163 | double msecs = (double)count[0] / 1000000; | ||
164 | |||
165 | fprintf(stderr, " %14.6f %-20s (msecs)", | ||
166 | msecs, event_name(counter)); | ||
167 | } else { | ||
168 | fprintf(stderr, " %14Ld %-20s (events)", | ||
169 | count[0], event_name(counter)); | ||
170 | } | ||
171 | if (scaled) | ||
172 | fprintf(stderr, " (scaled from %.2f%%)", | ||
173 | (double) count[2] / count[1] * 100); | ||
174 | fprintf(stderr, "\n"); | ||
175 | } | ||
176 | |||
112 | static int do_perfstat(int argc, const char **argv) | 177 | static int do_perfstat(int argc, const char **argv) |
113 | { | 178 | { |
114 | unsigned long long t0, t1; | 179 | unsigned long long t0, t1; |
115 | int counter; | 180 | int counter; |
116 | ssize_t res; | ||
117 | int status; | 181 | int status; |
118 | int pid; | 182 | int pid; |
119 | 183 | ||
@@ -149,55 +213,10 @@ static int do_perfstat(int argc, const char **argv) | |||
149 | argv[0]); | 213 | argv[0]); |
150 | fprintf(stderr, "\n"); | 214 | fprintf(stderr, "\n"); |
151 | 215 | ||
152 | for (counter = 0; counter < nr_counters; counter++) { | 216 | for (counter = 0; counter < nr_counters; counter++) |
153 | int cpu, nv; | 217 | print_counter(counter); |
154 | __u64 count[3], single_count[3]; | ||
155 | int scaled; | ||
156 | |||
157 | count[0] = count[1] = count[2] = 0; | ||
158 | nv = scale ? 3 : 1; | ||
159 | for (cpu = 0; cpu < nr_cpus; cpu ++) { | ||
160 | res = read(fd[cpu][counter], | ||
161 | single_count, nv * sizeof(__u64)); | ||
162 | assert(res == nv * sizeof(__u64)); | ||
163 | |||
164 | count[0] += single_count[0]; | ||
165 | if (scale) { | ||
166 | count[1] += single_count[1]; | ||
167 | count[2] += single_count[2]; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | scaled = 0; | ||
172 | if (scale) { | ||
173 | if (count[2] == 0) { | ||
174 | fprintf(stderr, " %14s %-20s\n", | ||
175 | "<not counted>", event_name(counter)); | ||
176 | continue; | ||
177 | } | ||
178 | if (count[2] < count[1]) { | ||
179 | scaled = 1; | ||
180 | count[0] = (unsigned long long) | ||
181 | ((double)count[0] * count[1] / count[2] + 0.5); | ||
182 | } | ||
183 | } | ||
184 | |||
185 | if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) || | ||
186 | event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) { | ||
187 | 218 | ||
188 | double msecs = (double)count[0] / 1000000; | ||
189 | 219 | ||
190 | fprintf(stderr, " %14.6f %-20s (msecs)", | ||
191 | msecs, event_name(counter)); | ||
192 | } else { | ||
193 | fprintf(stderr, " %14Ld %-20s (events)", | ||
194 | count[0], event_name(counter)); | ||
195 | } | ||
196 | if (scaled) | ||
197 | fprintf(stderr, " (scaled from %.2f%%)", | ||
198 | (double) count[2] / count[1] * 100); | ||
199 | fprintf(stderr, "\n"); | ||
200 | } | ||
201 | fprintf(stderr, "\n"); | 220 | fprintf(stderr, "\n"); |
202 | fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", | 221 | fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", |
203 | (double)(t1-t0)/1e6); | 222 | (double)(t1-t0)/1e6); |
@@ -212,7 +231,6 @@ static void skip_signal(int signo) | |||
212 | 231 | ||
213 | static const char * const stat_usage[] = { | 232 | static const char * const stat_usage[] = { |
214 | "perf stat [<options>] <command>", | 233 | "perf stat [<options>] <command>", |
215 | "perf stat [<options>] -- <command> [<options>]", | ||
216 | NULL | 234 | NULL |
217 | }; | 235 | }; |
218 | 236 | ||