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