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