1e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/*
2e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *
3e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * sched-pipe.c
4e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *
5e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * pipe: Benchmark for pipe()
6e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *
7e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Based on pipe-test-1m.c by Ingo Molnar <mingo@redhat.com>
8e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *  http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
9e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
10e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *
11e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */
12e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
13e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../perf.h"
14e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../util/util.h"
15e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../util/parse-options.h"
16e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../builtin.h"
17e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "bench.h"
18e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
19e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <unistd.h>
20e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <stdio.h>
21e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <stdlib.h>
22e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <signal.h>
23e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/wait.h>
24e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <linux/unistd.h>
25e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <string.h>
26e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <errno.h>
27e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <assert.h>
28e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/time.h>
29e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/types.h>
30e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
31e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define LOOPS_DEFAULT 1000000
32e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int loops = LOOPS_DEFAULT;
33e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
34e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const struct option options[] = {
35e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	OPT_INTEGER('l', "loop", &loops,
36e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		    "Specify number of loops"),
37e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	OPT_END()
38e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng};
39e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
40e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic const char * const bench_sched_pipe_usage[] = {
41e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	"perf bench sched pipe <options>",
42e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	NULL
43e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng};
44e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
45e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint bench_sched_pipe(int argc, const char **argv,
46e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		     const char *prefix __used)
47e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{
48e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng        /* ANDROID_CHANGE_BEGIN */
49e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#ifndef __BIONIC__
50e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int pipe_1[2], pipe_2[2];
51e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int m = 0, i;
52e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	struct timeval start, stop, diff;
53e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	unsigned long long result_usec = 0;
54e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
55e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	/*
56e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	 * why does "ret" exist?
57e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	 * discarding returned value of read(), write()
58e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	 * causes error in building environment for perf
59e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	 */
60e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	int __used ret, wait_stat;
61e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	pid_t pid, retpid;
62e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
63e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	argc = parse_options(argc, argv, options,
64e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			     bench_sched_pipe_usage, 0);
65e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
66e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	assert(!pipe(pipe_1));
67e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	assert(!pipe(pipe_2));
68e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
69e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	pid = fork();
70e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	assert(pid >= 0);
71e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
72e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	gettimeofday(&start, NULL);
73e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
74e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (!pid) {
75e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		for (i = 0; i < loops; i++) {
76e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			ret = read(pipe_1[0], &m, sizeof(int));
77e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			ret = write(pipe_2[1], &m, sizeof(int));
78e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		}
79e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	} else {
80e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		for (i = 0; i < loops; i++) {
81e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			ret = write(pipe_1[1], &m, sizeof(int));
82e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			ret = read(pipe_2[0], &m, sizeof(int));
83e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		}
84e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
85e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
86e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	gettimeofday(&stop, NULL);
87e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	timersub(&stop, &start, &diff);
88e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
89e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	if (pid) {
90e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		retpid = waitpid(pid, &wait_stat, 0);
91e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		assert((retpid == pid) && WIFEXITED(wait_stat));
92e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	} else {
93e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		exit(0);
94e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
95e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
96e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	switch (bench_format) {
97e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	case BENCH_FORMAT_DEFAULT:
98e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		printf("# Executed %d pipe operations between two tasks\n\n",
99e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			loops);
100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		result_usec = diff.tv_sec * 1000000;
102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		result_usec += diff.tv_usec;
103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		       diff.tv_sec,
106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		       (unsigned long) (diff.tv_usec/1000));
107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		printf(" %14lf usecs/op\n",
109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		       (double)result_usec / (double)loops);
110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		printf(" %14d ops/sec\n",
111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		       (int)((double)loops /
112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng			     ((double)result_usec / (double)1000000)));
113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		break;
114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	case BENCH_FORMAT_SIMPLE:
116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		printf("%lu.%03lu\n",
117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		       diff.tv_sec,
118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		       (unsigned long) (diff.tv_usec / 1000));
119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		break;
120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	default:
122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		/* reaching here is something disaster */
123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		fprintf(stderr, "Unknown format:%d\n", bench_format);
124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		exit(1);
125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng		break;
126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	}
127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif
128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng        /* ANDROID_CHANGE_END */
129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng
130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng	return 0;
131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}
132