| 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 |