xref: /minix3/external/bsd/libevent/dist/test/bench_cascade.c (revision e985b929927b5932e3b68f4b50587d458900107a)
1*e985b929SDavid van Moolenbroek /*	$NetBSD: bench_cascade.c,v 1.1.1.1 2013/04/11 16:43:32 christos Exp $	*/
2*e985b929SDavid van Moolenbroek /*
3*e985b929SDavid van Moolenbroek  * Copyright 2007-2012 Niels Provos and Nick Mathewson
4*e985b929SDavid van Moolenbroek  *
5*e985b929SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*e985b929SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
7*e985b929SDavid van Moolenbroek  * are met:
8*e985b929SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
9*e985b929SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
10*e985b929SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
11*e985b929SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
12*e985b929SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
13*e985b929SDavid van Moolenbroek  * 4. The name of the author may not be used to endorse or promote products
14*e985b929SDavid van Moolenbroek  *    derived from this software without specific prior written permission.
15*e985b929SDavid van Moolenbroek  *
16*e985b929SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*e985b929SDavid van Moolenbroek  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*e985b929SDavid van Moolenbroek  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*e985b929SDavid van Moolenbroek  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*e985b929SDavid van Moolenbroek  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*e985b929SDavid van Moolenbroek  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*e985b929SDavid van Moolenbroek  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*e985b929SDavid van Moolenbroek  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*e985b929SDavid van Moolenbroek  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*e985b929SDavid van Moolenbroek  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*e985b929SDavid van Moolenbroek  *
27*e985b929SDavid van Moolenbroek  */
28*e985b929SDavid van Moolenbroek 
29*e985b929SDavid van Moolenbroek #include "event2/event-config.h"
30*e985b929SDavid van Moolenbroek #include <sys/cdefs.h>
31*e985b929SDavid van Moolenbroek __RCSID("$NetBSD: bench_cascade.c,v 1.1.1.1 2013/04/11 16:43:32 christos Exp $");
32*e985b929SDavid van Moolenbroek 
33*e985b929SDavid van Moolenbroek #include <sys/types.h>
34*e985b929SDavid van Moolenbroek #include <sys/stat.h>
35*e985b929SDavid van Moolenbroek #ifdef _EVENT_HAVE_SYS_TIME_H
36*e985b929SDavid van Moolenbroek #include <sys/time.h>
37*e985b929SDavid van Moolenbroek #endif
38*e985b929SDavid van Moolenbroek #ifdef WIN32
39*e985b929SDavid van Moolenbroek #define WIN32_LEAN_AND_MEAN
40*e985b929SDavid van Moolenbroek #include <windows.h>
41*e985b929SDavid van Moolenbroek #else
42*e985b929SDavid van Moolenbroek #include <sys/socket.h>
43*e985b929SDavid van Moolenbroek #include <sys/resource.h>
44*e985b929SDavid van Moolenbroek #endif
45*e985b929SDavid van Moolenbroek #include <signal.h>
46*e985b929SDavid van Moolenbroek #include <fcntl.h>
47*e985b929SDavid van Moolenbroek #include <stdlib.h>
48*e985b929SDavid van Moolenbroek #include <stdio.h>
49*e985b929SDavid van Moolenbroek #include <string.h>
50*e985b929SDavid van Moolenbroek #ifdef _EVENT_HAVE_UNISTD_H
51*e985b929SDavid van Moolenbroek #include <unistd.h>
52*e985b929SDavid van Moolenbroek #endif
53*e985b929SDavid van Moolenbroek #include <errno.h>
54*e985b929SDavid van Moolenbroek 
55*e985b929SDavid van Moolenbroek #include <event.h>
56*e985b929SDavid van Moolenbroek #include <evutil.h>
57*e985b929SDavid van Moolenbroek 
58*e985b929SDavid van Moolenbroek /*
59*e985b929SDavid van Moolenbroek  * This benchmark tests how quickly we can propagate a write down a chain
60*e985b929SDavid van Moolenbroek  * of socket pairs.  We start by writing to the first socket pair and all
61*e985b929SDavid van Moolenbroek  * events will fire subsequently until the last socket pair has been reached
62*e985b929SDavid van Moolenbroek  * and the benchmark terminates.
63*e985b929SDavid van Moolenbroek  */
64*e985b929SDavid van Moolenbroek 
65*e985b929SDavid van Moolenbroek static int fired;
66*e985b929SDavid van Moolenbroek static evutil_socket_t *pipes;
67*e985b929SDavid van Moolenbroek static struct event *events;
68*e985b929SDavid van Moolenbroek 
69*e985b929SDavid van Moolenbroek static void
read_cb(evutil_socket_t fd,short which,void * arg)70*e985b929SDavid van Moolenbroek read_cb(evutil_socket_t fd, short which, void *arg)
71*e985b929SDavid van Moolenbroek {
72*e985b929SDavid van Moolenbroek 	char ch;
73*e985b929SDavid van Moolenbroek 	evutil_socket_t sock = (evutil_socket_t)(ev_intptr_t)arg;
74*e985b929SDavid van Moolenbroek 
75*e985b929SDavid van Moolenbroek 	recv(fd, &ch, sizeof(ch), 0);
76*e985b929SDavid van Moolenbroek 	if (sock >= 0) {
77*e985b929SDavid van Moolenbroek 		if (send(sock, "e", 1, 0) < 0)
78*e985b929SDavid van Moolenbroek 			perror("send");
79*e985b929SDavid van Moolenbroek 	}
80*e985b929SDavid van Moolenbroek 	fired++;
81*e985b929SDavid van Moolenbroek }
82*e985b929SDavid van Moolenbroek 
83*e985b929SDavid van Moolenbroek static struct timeval *
run_once(int num_pipes)84*e985b929SDavid van Moolenbroek run_once(int num_pipes)
85*e985b929SDavid van Moolenbroek {
86*e985b929SDavid van Moolenbroek 	int i;
87*e985b929SDavid van Moolenbroek 	evutil_socket_t *cp;
88*e985b929SDavid van Moolenbroek 	static struct timeval ts, te, tv_timeout;
89*e985b929SDavid van Moolenbroek 
90*e985b929SDavid van Moolenbroek 	events = calloc(num_pipes, sizeof(struct event));
91*e985b929SDavid van Moolenbroek 	pipes = calloc(num_pipes * 2, sizeof(evutil_socket_t));
92*e985b929SDavid van Moolenbroek 
93*e985b929SDavid van Moolenbroek 	if (events == NULL || pipes == NULL) {
94*e985b929SDavid van Moolenbroek 		perror("malloc");
95*e985b929SDavid van Moolenbroek 		exit(1);
96*e985b929SDavid van Moolenbroek 	}
97*e985b929SDavid van Moolenbroek 
98*e985b929SDavid van Moolenbroek 	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
99*e985b929SDavid van Moolenbroek 		if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) {
100*e985b929SDavid van Moolenbroek 			perror("socketpair");
101*e985b929SDavid van Moolenbroek 			exit(1);
102*e985b929SDavid van Moolenbroek 		}
103*e985b929SDavid van Moolenbroek 	}
104*e985b929SDavid van Moolenbroek 
105*e985b929SDavid van Moolenbroek 	/* measurements includes event setup */
106*e985b929SDavid van Moolenbroek 	evutil_gettimeofday(&ts, NULL);
107*e985b929SDavid van Moolenbroek 
108*e985b929SDavid van Moolenbroek 	/* provide a default timeout for events */
109*e985b929SDavid van Moolenbroek 	evutil_timerclear(&tv_timeout);
110*e985b929SDavid van Moolenbroek 	tv_timeout.tv_sec = 60;
111*e985b929SDavid van Moolenbroek 
112*e985b929SDavid van Moolenbroek 	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
113*e985b929SDavid van Moolenbroek 		evutil_socket_t fd = i < num_pipes - 1 ? cp[3] : -1;
114*e985b929SDavid van Moolenbroek 		event_set(&events[i], cp[0], EV_READ, read_cb,
115*e985b929SDavid van Moolenbroek 		    (void *)(ev_intptr_t)fd);
116*e985b929SDavid van Moolenbroek 		event_add(&events[i], &tv_timeout);
117*e985b929SDavid van Moolenbroek 	}
118*e985b929SDavid van Moolenbroek 
119*e985b929SDavid van Moolenbroek 	fired = 0;
120*e985b929SDavid van Moolenbroek 
121*e985b929SDavid van Moolenbroek 	/* kick everything off with a single write */
122*e985b929SDavid van Moolenbroek 	if (send(pipes[1], "e", 1, 0) < 0)
123*e985b929SDavid van Moolenbroek 		perror("send");
124*e985b929SDavid van Moolenbroek 
125*e985b929SDavid van Moolenbroek 	event_dispatch();
126*e985b929SDavid van Moolenbroek 
127*e985b929SDavid van Moolenbroek 	evutil_gettimeofday(&te, NULL);
128*e985b929SDavid van Moolenbroek 	evutil_timersub(&te, &ts, &te);
129*e985b929SDavid van Moolenbroek 
130*e985b929SDavid van Moolenbroek 	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
131*e985b929SDavid van Moolenbroek 		event_del(&events[i]);
132*e985b929SDavid van Moolenbroek 		close(cp[0]);
133*e985b929SDavid van Moolenbroek 		close(cp[1]);
134*e985b929SDavid van Moolenbroek 	}
135*e985b929SDavid van Moolenbroek 
136*e985b929SDavid van Moolenbroek 	free(pipes);
137*e985b929SDavid van Moolenbroek 	free(events);
138*e985b929SDavid van Moolenbroek 
139*e985b929SDavid van Moolenbroek 	return (&te);
140*e985b929SDavid van Moolenbroek }
141*e985b929SDavid van Moolenbroek 
142*e985b929SDavid van Moolenbroek int
main(int argc,char ** argv)143*e985b929SDavid van Moolenbroek main(int argc, char **argv)
144*e985b929SDavid van Moolenbroek {
145*e985b929SDavid van Moolenbroek #ifndef WIN32
146*e985b929SDavid van Moolenbroek 	struct rlimit rl;
147*e985b929SDavid van Moolenbroek #endif
148*e985b929SDavid van Moolenbroek 	int i, c;
149*e985b929SDavid van Moolenbroek 	struct timeval *tv;
150*e985b929SDavid van Moolenbroek 
151*e985b929SDavid van Moolenbroek 	int num_pipes = 100;
152*e985b929SDavid van Moolenbroek 	while ((c = getopt(argc, argv, "n:")) != -1) {
153*e985b929SDavid van Moolenbroek 		switch (c) {
154*e985b929SDavid van Moolenbroek 		case 'n':
155*e985b929SDavid van Moolenbroek 			num_pipes = atoi(optarg);
156*e985b929SDavid van Moolenbroek 			break;
157*e985b929SDavid van Moolenbroek 		default:
158*e985b929SDavid van Moolenbroek 			fprintf(stderr, "Illegal argument \"%c\"\n", c);
159*e985b929SDavid van Moolenbroek 			exit(1);
160*e985b929SDavid van Moolenbroek 		}
161*e985b929SDavid van Moolenbroek 	}
162*e985b929SDavid van Moolenbroek 
163*e985b929SDavid van Moolenbroek #ifndef WIN32
164*e985b929SDavid van Moolenbroek 	rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
165*e985b929SDavid van Moolenbroek 	if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
166*e985b929SDavid van Moolenbroek 		perror("setrlimit");
167*e985b929SDavid van Moolenbroek 		exit(1);
168*e985b929SDavid van Moolenbroek 	}
169*e985b929SDavid van Moolenbroek #endif
170*e985b929SDavid van Moolenbroek 
171*e985b929SDavid van Moolenbroek 	event_init();
172*e985b929SDavid van Moolenbroek 
173*e985b929SDavid van Moolenbroek 	for (i = 0; i < 25; i++) {
174*e985b929SDavid van Moolenbroek 		tv = run_once(num_pipes);
175*e985b929SDavid van Moolenbroek 		if (tv == NULL)
176*e985b929SDavid van Moolenbroek 			exit(1);
177*e985b929SDavid van Moolenbroek 		fprintf(stdout, "%ld\n",
178*e985b929SDavid van Moolenbroek 			tv->tv_sec * 1000000L + tv->tv_usec);
179*e985b929SDavid van Moolenbroek 	}
180*e985b929SDavid van Moolenbroek 
181*e985b929SDavid van Moolenbroek 	exit(0);
182*e985b929SDavid van Moolenbroek }
183