xref: /haiku/src/tests/system/benchmarks/ctxbench.c (revision 83b1a68c52ba3e0e8796282759f694b7fdddf06d)
1 /*
2  * gcc -Wall -Werror -O3 -static -o ctx ctx.c
3  */
4 
5 #define errx(x,y...) { fprintf(stderr, y); fprintf(stderr, "\n"); exit(x); }
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <sys/time.h>
11 #include <signal.h>
12 #if defined (LWP)
13 #include <sys/ucontext.h>
14 #include <sys/lwp.h>
15 #endif
16 
17 #define ITERATIONS	8192
18 #define PASSES		50
19 
20 int fd0[2], fd1[2];
21 unsigned long elapsed_times[ITERATIONS];
22 unsigned long overhead;
23 pid_t childpid;
24 
25 static void
26 usage(void)
27 {
28 	printf("ctx [-hl]\n");
29 	exit(1);
30 }
31 
32 static void
33 child(void)
34 {
35 	int ch;
36 
37 	ch = 0;
38 	if (write(fd1[1], &ch, 1) != 1)
39 		errx(1, "child write failed");
40 	while (1) {
41 		if (read(fd0[0], &ch, 1) != 1)
42 			errx(1, "child read failed");
43 		if (write(fd1[1], &ch, 1) != 1)
44 			errx(1, "child write failed");
45 	}
46 }
47 
48 static void
49 dump_results(void)
50 {
51 	unsigned long min_time, max_time, sum;
52 	int i;
53 
54 	min_time = elapsed_times[0];
55 	max_time = elapsed_times[0];
56 	sum = 0;
57 	for (i=1; i<ITERATIONS; i++) {
58 		if (elapsed_times[i] < min_time)
59 			min_time = elapsed_times[i];
60 		if (elapsed_times[i] > max_time)
61 			max_time = elapsed_times[i];
62 		sum += elapsed_times[i] - overhead;
63 	}
64 	min_time -= overhead;
65 	max_time -= overhead;
66 
67 	printf("min latency: %f\n", (double)min_time / PASSES);
68 	printf("max latency: %f\n", (double)max_time / PASSES);
69 	printf("mean latency: %f\n", (double)sum / ITERATIONS / PASSES);
70 }
71 
72 int
73 main(int argc, char *argv[])
74 {
75 	int i, ch, count;
76 	struct timeval before, after;
77 	unsigned long elapsed;
78 	int use_lwps = 0;
79 
80 	memset(elapsed_times, 0, ITERATIONS);
81 
82 	while ((ch = getopt(argc, argv, "hl")) != -1) {
83 		switch (ch) {
84 		case 'l':
85 #if defined(LWP)
86 			use_lwps = 1;
87 #else
88 			errx(1, "not supported");
89 #endif
90 			break;
91 		case 'h':
92 			usage();
93 		}
94 	}
95 	argc -= optind;
96 	argv += optind;
97 
98 	sleep(1);
99 
100 	if (pipe(fd0) != 0)
101 		errx(1, "Unable to create pipe");
102 	if (pipe(fd1) != 0)
103 		errx(1, "Unable to create pipe");
104 
105 	/*
106 	 * Determine overhead
107 	 */
108 	for (count=0; count<2; count++) {
109 		gettimeofday(&before, NULL);
110 		for (i=0; i<2*(PASSES/2); i++) {
111 			ch = 0;
112 			write(fd0[1], &ch, 1);
113 			read(fd0[0], &ch, 1);
114 		}
115 		gettimeofday(&after, NULL);
116 		overhead = 1000000 * (after.tv_sec - before.tv_sec);
117 		overhead += after.tv_usec - before.tv_usec;
118 	}
119 
120 	if (use_lwps) {
121 #if defined(LWP)
122 		ucontext_t u;
123 		ucontext_t *contextp;
124 		int stacksize = 65536;
125 		void *stackbase;
126 		lwpid_t l;
127 		int error;
128 
129 		getcontext(&u);
130 		contextp = (ucontext_t *)malloc(sizeof(ucontext_t));
131 		stackbase = malloc(stacksize);
132 		sigprocmask(SIG_SETMASK, NULL, &contextp->uc_sigmask);
133 		_lwp_makecontext(contextp, child, NULL, NULL,
134 			stackbase, stacksize);
135 		error = _lwp_create(contextp, 0, &l);
136 		if (error)
137 			errx(1, "error _lwp_create");
138 #endif
139 	} else {
140 		switch (childpid = fork()) {
141 		case 0:		/* child */
142 			child();
143 		case -1:	/* error */
144 			errx(1, "error forking");
145 			break;
146 		}
147 	}
148 
149 	ch = 0;
150 	if (read(fd1[0], &ch, 1) != 1)
151 		errx(1, "parent read failed");
152 	for (count=0; count<ITERATIONS; count++) {
153 		gettimeofday(&before, NULL);
154 		for (i=0; i<PASSES/2; i++) {
155 			ch = 0;
156 			if (write(fd0[1], &ch, 1) != 1)
157 				errx(1, "parent write failed");
158 			if (read(fd1[0], &ch, 1) != 1)
159 				errx(1, "parent read failed");
160 		}
161 		gettimeofday(&after, NULL);
162 		elapsed = 1000000 * (after.tv_sec - before.tv_sec);
163 		elapsed += after.tv_usec - before.tv_usec;
164 		elapsed_times[count] = elapsed;
165 	}
166 
167 	if (!use_lwps)
168 		kill(childpid, SIGTERM);
169 	dump_results();
170 
171 	return (0);
172 }
173 
174 
175 /*
176  * PMAX_SA:
177  *
178  * min latency: 93.100000
179  * max latency: 150.700000
180  * mean latency: 100.857581
181  *
182  * PMAX_CHOOSEPROC:
183  *
184  * min latency: 49.350000
185  * max latency: 76.750000
186  * mean latency: 54.141626
187  *
188  * PMAX_OLD:
189  *
190  * min latency: 54.750000
191  * max latency: 76.050000
192  * mean latency: 60.088654
193  *
194  * HP300_SA:
195  *
196  * min latency: 352.560000
197  * max latency: 402.960000
198  * mean latency: 367.836250
199  *
200  * HP300_CHOOSEPROC:
201  *
202  * min latency: 129.200000
203  * max latency: 187.040000
204  * mean latency: 142.528223
205  *
206  * HP300_OLD:
207  *
208  * min latency: 357.360000
209  * max latency: 414.400000
210  * mean latency: 372.436104
211  *
212  */
213