diff options
-rw-r--r-- | tools/perf/bench/sched-pipe.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c new file mode 100644 index 000000000000..3214ed20b1aa --- /dev/null +++ b/tools/perf/bench/sched-pipe.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * | ||
3 | * builtin-bench-pipe.c | ||
4 | * | ||
5 | * pipe: Benchmark for pipe() | ||
6 | * | ||
7 | * Based on pipe-test-1m.c by Ingo Molnar <mingo@redhat.com> | ||
8 | * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c | ||
9 | * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include "../perf.h" | ||
14 | #include "../util/util.h" | ||
15 | #include "../util/parse-options.h" | ||
16 | #include "../builtin.h" | ||
17 | #include "bench.h" | ||
18 | |||
19 | #include <unistd.h> | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <signal.h> | ||
23 | #include <sys/wait.h> | ||
24 | #include <linux/unistd.h> | ||
25 | #include <string.h> | ||
26 | #include <errno.h> | ||
27 | #include <assert.h> | ||
28 | #include <sys/time.h> | ||
29 | |||
30 | #define LOOPS_DEFAULT 1000000 | ||
31 | static int loops = LOOPS_DEFAULT; | ||
32 | static int simple = 0; | ||
33 | |||
34 | static const struct option options[] = { | ||
35 | OPT_INTEGER('l', "loop", &loops, | ||
36 | "Specify number of loops"), | ||
37 | OPT_BOOLEAN('s', "simple-output", &simple, | ||
38 | "Do simple output (this maybe useful for" | ||
39 | "processing by scripts or graph tools like gnuplot)"), | ||
40 | OPT_END() | ||
41 | }; | ||
42 | |||
43 | static const char * const bench_sched_pipe_usage[] = { | ||
44 | "perf bench sched pipe <options>", | ||
45 | NULL | ||
46 | }; | ||
47 | |||
48 | int bench_sched_pipe(int argc, const char **argv, | ||
49 | const char *prefix __used) | ||
50 | { | ||
51 | int pipe_1[2], pipe_2[2]; | ||
52 | int m = 0, i; | ||
53 | struct timeval start, stop, diff; | ||
54 | unsigned long long result_usec = 0; | ||
55 | |||
56 | /* | ||
57 | * why does "ret" exist? | ||
58 | * discarding returned value of read(), write() | ||
59 | * causes error in building environment for perf | ||
60 | */ | ||
61 | int ret; | ||
62 | pid_t pid; | ||
63 | |||
64 | argc = parse_options(argc, argv, options, | ||
65 | bench_sched_pipe_usage, 0); | ||
66 | |||
67 | assert(!pipe(pipe_1)); | ||
68 | assert(!pipe(pipe_2)); | ||
69 | |||
70 | pid = fork(); | ||
71 | assert(pid >= 0); | ||
72 | |||
73 | gettimeofday(&start, NULL); | ||
74 | |||
75 | if (!pid) { | ||
76 | for (i = 0; i < loops; i++) { | ||
77 | ret = read(pipe_1[0], &m, sizeof(int)); | ||
78 | ret = write(pipe_2[1], &m, sizeof(int)); | ||
79 | } | ||
80 | } else { | ||
81 | for (i = 0; i < loops; i++) { | ||
82 | ret = write(pipe_1[1], &m, sizeof(int)); | ||
83 | ret = read(pipe_2[0], &m, sizeof(int)); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | gettimeofday(&stop, NULL); | ||
88 | timersub(&stop, &start, &diff); | ||
89 | |||
90 | if (pid) | ||
91 | return 0; | ||
92 | |||
93 | if (simple) | ||
94 | printf("%lu.%03lu\n", | ||
95 | diff.tv_sec, diff.tv_usec / 1000); | ||
96 | else { | ||
97 | printf("(executing %d pipe operations between two tasks)\n\n", | ||
98 | loops); | ||
99 | |||
100 | result_usec = diff.tv_sec * 1000000; | ||
101 | result_usec += diff.tv_usec; | ||
102 | |||
103 | printf("\tTotal time:%lu.%03lu sec\n", | ||
104 | diff.tv_sec, diff.tv_usec / 1000); | ||
105 | printf("\t\t%lf usecs/op\n", | ||
106 | (double)result_usec / (double)loops); | ||
107 | printf("\t\t%d ops/sec\n", | ||
108 | (int)((double)loops / | ||
109 | ((double)result_usec / (double)1000000))); | ||
110 | } | ||
111 | |||
112 | return 0; | ||
113 | } | ||