15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2003 Niels Provos <provos@citi.umich.edu>
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4. The name of the author may not be used to endorse or promote products
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    derived from this software without specific prior written permission.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Mon 03/10/2003 - Modified by Davide Libenzi <davidel@xmailserver.org>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     Added chain event propagation to improve the sensitivity of
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     the measure respect to the event loop efficency.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h>
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/resource.h>
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <event.h>
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <evutil.h>
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int count, writes, fired;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int *pipes;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int num_pipes, num_active, num_writes;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct event *events;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)read_cb(int fd, short which, void *arg)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	long idx = (long) arg, widx = idx + 1;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u_char ch;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	count += read(fd, &ch, sizeof(ch));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (writes) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (widx >= num_pipes)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			widx -= num_pipes;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write(pipes[2 * widx + 1], "e", 1);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		writes--;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		fired++;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct timeval *
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)run_once(void)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int *cp, space;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	long i;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	static struct timeval ts, te;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		event_del(&events[i]);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *) i);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		event_add(&events[i], NULL);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	fired = 0;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	space = num_pipes / num_active;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	space = space * 2;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < num_active; i++, fired++)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write(pipes[i * space + 1], "e", 1);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	count = 0;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	writes = num_writes;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{ int xcount = 0;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	gettimeofday(&ts, NULL);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	do {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xcount++;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} while (count != fired);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	gettimeofday(&te, NULL);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evutil_timersub(&te, &ts, &te);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (&te);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)main (int argc, char **argv)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WIN32
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rlimit rl;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i, c;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct timeval *tv;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int *cp;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	num_pipes = 100;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	num_active = 1;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	num_writes = num_pipes;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((c = getopt(argc, argv, "n:a:w:")) != -1) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (c) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 'n':
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			num_pipes = atoi(optarg);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 'a':
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			num_active = atoi(optarg);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case 'w':
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			num_writes = atoi(optarg);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			fprintf(stderr, "Illegal argument \"%c\"\n", c);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exit(1);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WIN32
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		perror("setrlimit");
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exit(1);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	events = calloc(num_pipes, sizeof(struct event));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pipes = calloc(num_pipes * 2, sizeof(int));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (events == NULL || pipes == NULL) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		perror("malloc");
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		exit(1);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	event_init();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef USE_PIPES
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (pipe(cp) == -1) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			perror("pipe");
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exit(1);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < 25; i++) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tv = run_once();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tv == NULL)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			exit(1);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		fprintf(stdout, "%ld\n",
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			tv->tv_sec * 1000000L + tv->tv_usec);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exit(0);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
189