OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2003 Niels Provos <provos@citi.umich.edu> | |
3 * All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * 4. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 * | |
27 * | |
28 * Mon 03/10/2003 - Modified by Davide Libenzi <davidel@xmailserver.org> | |
29 * | |
30 * Added chain event propagation to improve the sensitivity of | |
31 * the measure respect to the event loop efficency. | |
32 * | |
33 * | |
34 */ | |
35 | |
36 #ifdef HAVE_CONFIG_H | |
37 #include "config.h" | |
38 #endif | |
39 | |
40 #include <sys/types.h> | |
41 #include <sys/stat.h> | |
42 #include <sys/time.h> | |
43 #ifdef WIN32 | |
44 #include <windows.h> | |
45 #else | |
46 #include <sys/socket.h> | |
47 #include <signal.h> | |
48 #include <sys/resource.h> | |
49 #endif | |
50 #include <fcntl.h> | |
51 #include <stdlib.h> | |
52 #include <stdio.h> | |
53 #include <string.h> | |
54 #include <unistd.h> | |
55 #include <errno.h> | |
56 | |
57 #include <event.h> | |
58 #include <evutil.h> | |
59 | |
60 | |
61 static int count, writes, fired; | |
62 static int *pipes; | |
63 static int num_pipes, num_active, num_writes; | |
64 static struct event *events; | |
65 | |
66 static void | |
67 read_cb(int fd, short which, void *arg) | |
68 { | |
69 long idx = (long) arg, widx = idx + 1; | |
70 u_char ch; | |
71 | |
72 count += read(fd, &ch, sizeof(ch)); | |
73 if (writes) { | |
74 if (widx >= num_pipes) | |
75 widx -= num_pipes; | |
76 write(pipes[2 * widx + 1], "e", 1); | |
77 writes--; | |
78 fired++; | |
79 } | |
80 } | |
81 | |
82 static struct timeval * | |
83 run_once(void) | |
84 { | |
85 int *cp, space; | |
86 long i; | |
87 static struct timeval ts, te; | |
88 | |
89 for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { | |
90 event_del(&events[i]); | |
91 event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (voi
d *) i); | |
92 event_add(&events[i], NULL); | |
93 } | |
94 | |
95 event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); | |
96 | |
97 fired = 0; | |
98 space = num_pipes / num_active; | |
99 space = space * 2; | |
100 for (i = 0; i < num_active; i++, fired++) | |
101 write(pipes[i * space + 1], "e", 1); | |
102 | |
103 count = 0; | |
104 writes = num_writes; | |
105 { int xcount = 0; | |
106 gettimeofday(&ts, NULL); | |
107 do { | |
108 event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); | |
109 xcount++; | |
110 } while (count != fired); | |
111 gettimeofday(&te, NULL); | |
112 | |
113 if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount,
count); | |
114 } | |
115 | |
116 evutil_timersub(&te, &ts, &te); | |
117 | |
118 return (&te); | |
119 } | |
120 | |
121 int | |
122 main (int argc, char **argv) | |
123 { | |
124 #ifndef WIN32 | |
125 struct rlimit rl; | |
126 #endif | |
127 int i, c; | |
128 struct timeval *tv; | |
129 int *cp; | |
130 | |
131 num_pipes = 100; | |
132 num_active = 1; | |
133 num_writes = num_pipes; | |
134 while ((c = getopt(argc, argv, "n:a:w:")) != -1) { | |
135 switch (c) { | |
136 case 'n': | |
137 num_pipes = atoi(optarg); | |
138 break; | |
139 case 'a': | |
140 num_active = atoi(optarg); | |
141 break; | |
142 case 'w': | |
143 num_writes = atoi(optarg); | |
144 break; | |
145 default: | |
146 fprintf(stderr, "Illegal argument \"%c\"\n", c); | |
147 exit(1); | |
148 } | |
149 } | |
150 | |
151 #ifndef WIN32 | |
152 rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; | |
153 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { | |
154 perror("setrlimit"); | |
155 exit(1); | |
156 } | |
157 #endif | |
158 | |
159 events = calloc(num_pipes, sizeof(struct event)); | |
160 pipes = calloc(num_pipes * 2, sizeof(int)); | |
161 if (events == NULL || pipes == NULL) { | |
162 perror("malloc"); | |
163 exit(1); | |
164 } | |
165 | |
166 event_init(); | |
167 | |
168 for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { | |
169 #ifdef USE_PIPES | |
170 if (pipe(cp) == -1) { | |
171 #else | |
172 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) { | |
173 #endif | |
174 perror("pipe"); | |
175 exit(1); | |
176 } | |
177 } | |
178 | |
179 for (i = 0; i < 25; i++) { | |
180 tv = run_once(); | |
181 if (tv == NULL) | |
182 exit(1); | |
183 fprintf(stdout, "%ld\n", | |
184 tv->tv_sec * 1000000L + tv->tv_usec); | |
185 } | |
186 | |
187 exit(0); | |
188 } | |
OLD | NEW |