aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2e03524a1de0..f9510eeeb6c7 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -64,7 +64,7 @@ static struct perf_counter_attr default_attrs[] = {
64 64
65static int system_wide = 0; 65static int system_wide = 0;
66static int verbose = 0; 66static int verbose = 0;
67static int nr_cpus = 0; 67static unsigned int nr_cpus = 0;
68static int run_idx = 0; 68static int run_idx = 0;
69 69
70static int run_count = 1; 70static int run_count = 1;
@@ -96,6 +96,10 @@ static u64 walltime_nsecs_noise;
96static u64 runtime_cycles_avg; 96static u64 runtime_cycles_avg;
97static u64 runtime_cycles_noise; 97static u64 runtime_cycles_noise;
98 98
99#define MATCH_EVENT(t, c, counter) \
100 (attrs[counter].type == PERF_TYPE_##t && \
101 attrs[counter].config == PERF_COUNT_##c)
102
99#define ERR_PERF_OPEN \ 103#define ERR_PERF_OPEN \
100"Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n" 104"Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n"
101 105
@@ -108,7 +112,8 @@ static void create_perf_stat_counter(int counter, int pid)
108 PERF_FORMAT_TOTAL_TIME_RUNNING; 112 PERF_FORMAT_TOTAL_TIME_RUNNING;
109 113
110 if (system_wide) { 114 if (system_wide) {
111 int cpu; 115 unsigned int cpu;
116
112 for (cpu = 0; cpu < nr_cpus; cpu++) { 117 for (cpu = 0; cpu < nr_cpus; cpu++) {
113 fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0); 118 fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0);
114 if (fd[cpu][counter] < 0 && verbose) 119 if (fd[cpu][counter] < 0 && verbose)
@@ -132,13 +137,8 @@ static void create_perf_stat_counter(int counter, int pid)
132 */ 137 */
133static inline int nsec_counter(int counter) 138static inline int nsec_counter(int counter)
134{ 139{
135 if (attrs[counter].type != PERF_TYPE_SOFTWARE) 140 if (MATCH_EVENT(SOFTWARE, SW_CPU_CLOCK, counter) ||
136 return 0; 141 MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
137
138 if (attrs[counter].config == PERF_COUNT_SW_CPU_CLOCK)
139 return 1;
140
141 if (attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK)
142 return 1; 142 return 1;
143 143
144 return 0; 144 return 0;
@@ -150,8 +150,8 @@ static inline int nsec_counter(int counter)
150static void read_counter(int counter) 150static void read_counter(int counter)
151{ 151{
152 u64 *count, single_count[3]; 152 u64 *count, single_count[3];
153 ssize_t res; 153 unsigned int cpu;
154 int cpu, nv; 154 size_t res, nv;
155 int scaled; 155 int scaled;
156 156
157 count = event_res[run_idx][counter]; 157 count = event_res[run_idx][counter];
@@ -165,6 +165,7 @@ static void read_counter(int counter)
165 165
166 res = read(fd[cpu][counter], single_count, nv * sizeof(u64)); 166 res = read(fd[cpu][counter], single_count, nv * sizeof(u64));
167 assert(res == nv * sizeof(u64)); 167 assert(res == nv * sizeof(u64));
168
168 close(fd[cpu][counter]); 169 close(fd[cpu][counter]);
169 fd[cpu][counter] = -1; 170 fd[cpu][counter] = -1;
170 171
@@ -192,15 +193,13 @@ static void read_counter(int counter)
192 /* 193 /*
193 * Save the full runtime - to allow normalization during printout: 194 * Save the full runtime - to allow normalization during printout:
194 */ 195 */
195 if (attrs[counter].type == PERF_TYPE_SOFTWARE && 196 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
196 attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK)
197 runtime_nsecs[run_idx] = count[0]; 197 runtime_nsecs[run_idx] = count[0];
198 if (attrs[counter].type == PERF_TYPE_HARDWARE && 198 if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter))
199 attrs[counter].config == PERF_COUNT_HW_CPU_CYCLES)
200 runtime_cycles[run_idx] = count[0]; 199 runtime_cycles[run_idx] = count[0];
201} 200}
202 201
203static int run_perf_stat(int argc, const char **argv) 202static int run_perf_stat(int argc __used, const char **argv)
204{ 203{
205 unsigned long long t0, t1; 204 unsigned long long t0, t1;
206 int status = 0; 205 int status = 0;
@@ -240,7 +239,8 @@ static int run_perf_stat(int argc, const char **argv)
240 /* 239 /*
241 * Wait until the parent tells us to go. 240 * Wait until the parent tells us to go.
242 */ 241 */
243 read(go_pipe[0], &buf, 1); 242 if (read(go_pipe[0], &buf, 1) == -1)
243 perror("unable to read pipe");
244 244
245 execvp(argv[0], (char **)argv); 245 execvp(argv[0], (char **)argv);
246 246
@@ -253,7 +253,8 @@ static int run_perf_stat(int argc, const char **argv)
253 */ 253 */
254 close(child_ready_pipe[1]); 254 close(child_ready_pipe[1]);
255 close(go_pipe[0]); 255 close(go_pipe[0]);
256 read(child_ready_pipe[0], &buf, 1); 256 if (read(child_ready_pipe[0], &buf, 1) == -1)
257 perror("unable to read pipe");
257 close(child_ready_pipe[0]); 258 close(child_ready_pipe[0]);
258 259
259 for (counter = 0; counter < nr_counters; counter++) 260 for (counter = 0; counter < nr_counters; counter++)
@@ -290,9 +291,7 @@ static void nsec_printout(int counter, u64 *count, u64 *noise)
290 291
291 fprintf(stderr, " %14.6f %-24s", msecs, event_name(counter)); 292 fprintf(stderr, " %14.6f %-24s", msecs, event_name(counter));
292 293
293 if (attrs[counter].type == PERF_TYPE_SOFTWARE && 294 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) {
294 attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK) {
295
296 if (walltime_nsecs_avg) 295 if (walltime_nsecs_avg)
297 fprintf(stderr, " # %10.3f CPUs ", 296 fprintf(stderr, " # %10.3f CPUs ",
298 (double)count[0] / (double)walltime_nsecs_avg); 297 (double)count[0] / (double)walltime_nsecs_avg);
@@ -305,9 +304,7 @@ static void abs_printout(int counter, u64 *count, u64 *noise)
305 fprintf(stderr, " %14Ld %-24s", count[0], event_name(counter)); 304 fprintf(stderr, " %14Ld %-24s", count[0], event_name(counter));
306 305
307 if (runtime_cycles_avg && 306 if (runtime_cycles_avg &&
308 attrs[counter].type == PERF_TYPE_HARDWARE && 307 MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) {
309 attrs[counter].config == PERF_COUNT_HW_INSTRUCTIONS) {
310
311 fprintf(stderr, " # %10.3f IPC ", 308 fprintf(stderr, " # %10.3f IPC ",
312 (double)count[0] / (double)runtime_cycles_avg); 309 (double)count[0] / (double)runtime_cycles_avg);
313 } else { 310 } else {
@@ -390,7 +387,7 @@ static void calc_avg(void)
390 event_res_avg[j]+1, event_res[i][j]+1); 387 event_res_avg[j]+1, event_res[i][j]+1);
391 update_avg("counter/2", j, 388 update_avg("counter/2", j,
392 event_res_avg[j]+2, event_res[i][j]+2); 389 event_res_avg[j]+2, event_res[i][j]+2);
393 if (event_scaled[i][j] != -1) 390 if (event_scaled[i][j] != (u64)-1)
394 update_avg("scaled", j, 391 update_avg("scaled", j,
395 event_scaled_avg + j, event_scaled[i]+j); 392 event_scaled_avg + j, event_scaled[i]+j);
396 else 393 else
@@ -510,11 +507,12 @@ static const struct option options[] = {
510 OPT_END() 507 OPT_END()
511}; 508};
512 509
513int cmd_stat(int argc, const char **argv, const char *prefix) 510int cmd_stat(int argc, const char **argv, const char *prefix __used)
514{ 511{
515 int status; 512 int status;
516 513
517 argc = parse_options(argc, argv, options, stat_usage, 0); 514 argc = parse_options(argc, argv, options, stat_usage,
515 PARSE_OPT_STOP_AT_NON_OPTION);
518 if (!argc) 516 if (!argc)
519 usage_with_options(stat_usage, options); 517 usage_with_options(stat_usage, options);
520 if (run_count <= 0 || run_count > MAX_RUN) 518 if (run_count <= 0 || run_count > MAX_RUN)
@@ -528,7 +526,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix)
528 526
529 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); 527 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
530 assert(nr_cpus <= MAX_NR_CPUS); 528 assert(nr_cpus <= MAX_NR_CPUS);
531 assert(nr_cpus >= 0); 529 assert((int)nr_cpus >= 0);
532 530
533 /* 531 /*
534 * We dont want to block the signals - that would cause 532 * We dont want to block the signals - that would cause