/*
* Copyright 2003 - 2007 Niels Provos < provos @ citi . umich . edu >
* Copyright 2007 - 2012 Niels Provos and Nick Mathewson
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1 . Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2 . Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 4 . The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
*
* Mon 03 / 10 / 2003 - Modified by Davide Libenzi < davidel @ xmailserver . org >
*
* Added chain event propagation to improve the sensitivity of
* the measure respect to the event loop efficency .
*
*
*/
#include "event2/event-config.h"
#include "../util-internal.h"
#include <sys/types.h>
#include <sys/stat.h>
#ifdef EVENT__HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <sys/socket.h>
#include <signal.h>
#include <sys/resource.h>
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef EVENT__HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifdef _WIN32
#include <getopt.h>
#endif
#include <event.h>
#include <evutil.h>
static ev_ssize_t count, fired;
static int writes, failures;
static evutil_socket_t *pipes;
static int num_pipes, num_active, num_writes;
static struct event *events;
static struct event_base *base;
static void
read_cb(evutil_socket_t fd, short which, void *arg)
{
ev_intptr_t idx = (ev_intptr_t) arg, widx = idx + 1 ;
unsigned char ch;
ev_ssize_t n;
n = recv(fd, (char *)&ch, sizeof (ch), 0 );
if (n >= 0 )
count += n;
else
failures++;
if (writes) {
if (widx >= num_pipes)
widx -= num_pipes;
n = send(pipes[2 * widx + 1 ], "e" , 1 , 0 );
if (n != 1 )
failures++;
writes--;
fired++;
}
}
static struct timeval *
run_once(void )
{
evutil_socket_t *cp, space;
long i;
static struct timeval ts, te;
for (cp = pipes, i = 0 ; i < num_pipes; i++, cp += 2 ) {
if (event_initialized(&events[i]))
event_del(&events[i]);
event_assign(&events[i], base, cp[0 ], EV_READ | EV_PERSIST, read_cb, (void *)(ev_intptr_t) i);
event_add(&events[i], NULL);
}
event_base_loop(base, EVLOOP_ONCE | EVLOOP_NONBLOCK);
fired = 0 ;
space = num_pipes / num_active;
space = space * 2 ;
for (i = 0 ; i < num_active; i++, fired++)
(void ) send(pipes[i * space + 1 ], "e" , 1 , 0 );
count = 0 ;
writes = num_writes;
{
int xcount = 0 ;
evutil_gettimeofday(&ts, NULL);
do {
event_base_loop(base, EVLOOP_ONCE | EVLOOP_NONBLOCK);
xcount++;
} while (count != fired);
evutil_gettimeofday(&te, NULL);
if (xcount != count)
fprintf(stderr, "Xcount: %d, Rcount: " EV_SSIZE_FMT "\n" ,
xcount, count);
}
evutil_timersub(&te, &ts, &te);
return (&te);
}
int
main(int argc, char **argv)
{
#ifdef EVENT__HAVE_SETRLIMIT
struct rlimit rl;
#endif
int i, c;
struct timeval *tv;
evutil_socket_t *cp;
const char **methods;
const char *method = NULL;
struct event_config *cfg = NULL;
#ifdef _WIN32
WSADATA WSAData;
WSAStartup(0 x101, &WSAData);
#endif
num_pipes = 100 ;
num_active = 1 ;
num_writes = num_pipes;
while ((c = getopt(argc, argv, "n:a:w:m:l" )) != -1 ) {
switch (c) {
case 'n' :
num_pipes = atoi(optarg);
break ;
case 'a' :
num_active = atoi(optarg);
break ;
case 'w' :
num_writes = atoi(optarg);
break ;
case 'm' :
method = optarg;
break ;
case 'l' :
methods = event_get_supported_methods();
fprintf(stdout, "Using Libevent %s. Available methods are:\n" ,
event_get_version());
for (i = 0 ; methods[i] != NULL; ++i)
printf(" %s\n" , methods[i]);
exit (0 );
default :
fprintf(stderr, "Illegal argument \" %c\"\n" , c);
exit (1 );
}
}
#ifdef EVENT__HAVE_SETRLIMIT
rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50 ;
if (setrlimit(RLIMIT_NOFILE, &rl) == -1 ) {
perror("setrlimit" );
exit (1 );
}
#endif
events = calloc(num_pipes, sizeof (struct event));
pipes = calloc(num_pipes * 2 , sizeof (evutil_socket_t));
if (events == NULL || pipes == NULL) {
perror("malloc" );
exit (1 );
}
if (method != NULL) {
cfg = event_config_new();
methods = event_get_supported_methods();
for (i = 0 ; methods[i] != NULL; ++i)
if (strcmp(methods[i], method))
event_config_avoid_method(cfg, methods[i]);
base = event_base_new_with_config(cfg);
event_config_free(cfg);
} else
base = event_base_new();
for (cp = pipes, i = 0 ; i < num_pipes; i++, cp += 2 ) {
#ifdef USE_PIPES
if (pipe(cp) == -1 ) {
#else
if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0 , cp) == -1 ) {
#endif
perror("pipe" );
exit (1 );
}
}
for (i = 0 ; i < 25 ; i++) {
tv = run_once();
if (tv == NULL)
exit (1 );
fprintf(stdout, "%ld\n" ,
tv->tv_sec * 1000000 L + tv->tv_usec);
}
exit (0 );
}
Messung V0.5 in Prozent C=100 H=79 G=90
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland