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