Adapt bench.c (from libev) to libuev, no libev/libevent API wrappers available

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2013-08-06 02:04:41 +02:00
1 parent d9f078a119
commit 0de9cb6321
3 files changed
+91 -117

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
bench
test test
.*.d .*.d
*.o *.o
+6 -2
View File
@@ -107,8 +107,12 @@ test: Makefile test.o $(STATICLIB)
@printf " TEST %s\n" $(STATICLIB) @printf " TEST %s\n" $(STATICLIB)
@$(CC) $(CPPFLAGS) -g -o test test.c $(STATICLIB) && ./test @$(CC) $(CPPFLAGS) -g -o test test.c $(STATICLIB) && ./test
check: clean bench: Makefile bench.o $(STATICLIB)
@$(CHECK) $(CHECK_FLAGS) $(CPPFLAGS) $(SRCS) @printf " BENCH %s\n" $(STATICLIB)
@$(CC) $(CPPFLAGS) -g -o bench bench.c $(STATICLIB) && ./bench
check:
@$(CHECK) $(CHECK_FLAGS) $(CPPFLAGS) $(SRCS) bench.c
clean: clean:
-@$(RM) $(TARGET) *.o test -@$(RM) $(TARGET) *.o test
+84 -115
View File
@@ -30,142 +30,117 @@
* Added chain event propagation to improve the sensitivity of * Added chain event propagation to improve the sensitivity of
* the measure respect to the event loop efficency. * the measure respect to the event loop efficency.
* *
* Sun 04/08/2013 - Modified by Joachim Nilsson <troglobit@gmail.com>
* *
* Adaptations for libuev, no libev/libevent API wrappers available.
* Reindent to Linux coding style
*/ */
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#else
#define USE_PIPES
#endif #endif
#include <sys/types.h> #include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/socket.h> #include <sys/types.h>
#include <sys/signal.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#if NATIVE #include "uev.h"
#include "ev.h"
#endif #define UNUSED(arg) arg __attribute__ ((unused))
#include <event.h>
typedef struct {
int index;
} myarg_t;
static int count, writes, fired;
static int *pipes;
static int num_pipes, num_active, num_writes; static int num_pipes, num_active, num_writes;
static struct event *events; static int timers, count, writes, fired;
static int timers, native; static myarg_t *args;
static struct ev_io *evio; static int *pipes;
static struct ev_timer *evto; static uev_t *evio;
static uev_t *evto;
void read_cb(int fd, short which, void *arg) static void read_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *arg, int UNUSED(events))
{ {
int idx = (int)arg, widx = idx + 1; int idx, widx;
u_char ch; u_char ch;
myarg_t *m = arg;
if (timers) { idx = m->index;
if (native) { widx = idx + 1;
#if NATIVE if (timers)
evto[idx].repeat = 10. + drand48(); uev_timer_set(&evto[idx], 10000 + drand48() * 1000, 0);
ev_timer_again(&evto[idx]);
#else
abort();
#endif
} else {
struct timeval tv;
event_del(&events[idx]);
tv.tv_sec = 10;
tv.tv_usec = drand48() * 1e6;
event_add(&events[idx], &tv);
}
}
count += read(fd, &ch, sizeof(ch)); count += read(w->fd, &ch, sizeof(ch));
if (writes) { if (writes) {
if (widx >= num_pipes) if (widx >= num_pipes)
widx -= num_pipes; widx -= num_pipes;
write(pipes[2 * widx + 1], "e", 1);
if (write(pipes[2 * widx + 1], "e", 1) < 0) {
perror("write()");
abort();
}
writes--; writes--;
fired++; fired++;
} }
} }
#if NATIVE static void timer_cb(uev_ctx_t UNUSED(*ctx), uev_t UNUSED(*w), void UNUSED(*arg), int UNUSED(events))
void read_thunk(struct ev_io *w, int revents)
{
read_cb(w->fd, revents, w->data);
}
void timer_cb(struct ev_timer *w, int revents)
{ {
/* nop */ /* nop */
} }
#endif
struct timeval *run_once(void) static struct timeval *run_once(uev_ctx_t *ctx)
{ {
int *cp, i, space; int *cp, i, space;
static struct timeval ta, ts, te, tv; static struct timeval ta, ts, te;
gettimeofday(&ta, NULL); gettimeofday(&ta, NULL);
for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
if (native) { uev_io_set(&evio[i], cp[0], UEV_READ);
#if NATIVE
if (ev_is_active(&evio[i]))
ev_io_stop(&evio[i]);
ev_io_set(&evio[i], cp[0], EV_READ); if (timers)
ev_io_start(&evio[i]); uev_timer_set(&evto[i], 10000 + drand48() * 1000, 0);
evto[i].repeat = 10. + drand48();
ev_timer_again(&evto[i]);
#else
abort();
#endif
} else {
event_del(&events[i]);
event_set(&events[i], cp[0], EV_READ | EV_PERSIST,
read_cb, (void *)i);
tv.tv_sec = 10.;
tv.tv_usec = drand48() * 1e6;
event_add(&events[i], timers ? &tv : 0);
}
} }
event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); uev_run(ctx, UEV_ONCE | UEV_NONBLOCK);
fired = 0; fired = 0;
space = num_pipes / num_active; space = num_pipes / num_active;
space = space * 2; space = space * 2;
for (i = 0; i < num_active; i++, fired++) for (i = 0; i < num_active; i++, fired++) {
write(pipes[i * space + 1], "e", 1); if (write(pipes[i * space + 1], "e", 1) < 0) {
perror("write()");
abort();
}
}
count = 0; count = 0;
writes = num_writes; writes = num_writes;
{ {
int xcount = 0; int xcount = 0;
gettimeofday(&ts, NULL); gettimeofday(&ts, NULL);
do { do {
event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); uev_run(ctx, UEV_ONCE | UEV_NONBLOCK);
xcount++; xcount++;
} while (count != fired); } while (count != fired);
gettimeofday(&te, NULL); gettimeofday(&te, NULL);
//if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count); // if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
} }
timersub(&te, &ta, &ta); timersub(&te, &ta, &ta);
@@ -181,64 +156,59 @@ int main(int argc, char **argv)
{ {
struct rlimit rl; struct rlimit rl;
int i, c; int i, c;
struct timeval *tv;
int *cp; int *cp;
uev_ctx_t ctx;
extern char *optarg; extern char *optarg;
num_pipes = 100; num_pipes = 100;
num_active = 1; num_active = 1;
num_writes = num_pipes; num_writes = num_pipes;
while ((c = getopt(argc, argv, "n:a:w:te")) != -1) { while ((c = getopt(argc, argv, "a:n:tw:")) != -1) {
switch (c) { switch (c) {
case 'n':
num_pipes = atoi(optarg);
break;
case 'a': case 'a':
num_active = atoi(optarg); num_active = atoi(optarg);
break; break;
case 'w':
num_writes = atoi(optarg); case 'n':
break; num_pipes = atoi(optarg);
case 'e':
native = 1;
break; break;
case 't': case 't':
timers = 1; timers = 1;
break; break;
case 'w':
num_writes = atoi(optarg);
break;
default: default:
fprintf(stderr, "Illegal argument \"%c\"\n", c); fprintf(stderr, "Illegal argument \"%c\"\n", c);
exit(1); exit(1);
} }
} }
#if 1
rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
perror("setrlimit"); perror("setrlimit");
} }
#endif
#if NATIVE args = calloc(num_pipes, sizeof(myarg_t));
evio = calloc(num_pipes, sizeof(struct ev_io)); evio = calloc(num_pipes, sizeof(uev_t));
evto = calloc(num_pipes, sizeof(struct ev_timer)); evto = calloc(num_pipes, sizeof(uev_t));
#endif pipes = calloc(num_pipes * 2, sizeof(int));
events = calloc(num_pipes, sizeof(struct event)); if (!args || !evio || !evto || !pipes) {
pipes = calloc(num_pipes * 2, sizeof(int)); perror("calloc");
if (events == NULL || pipes == NULL) {
perror("malloc");
exit(1); exit(1);
} }
event_init(); uev_init(&ctx);
for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
#if NATIVE if (timers)
if (native) { uev_timer_init(&ctx, &evto[i], timer_cb, NULL, 0, 0);
ev_init(&evto[i], timer_cb); args[i].index = i;
ev_init(&evio[i], read_thunk); uev_io_init(&ctx, &evio[i], read_cb, &args[i], -1, UEV_READ);
evio[i].data = (void *)i;
}
#endif
#ifdef USE_PIPES #ifdef USE_PIPES
if (pipe(cp) == -1) { if (pipe(cp) == -1) {
#else #else
@@ -249,11 +219,10 @@ int main(int argc, char **argv)
} }
} }
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++)
tv = run_once(); run_once(&ctx);
}
exit(0); return 0;
} }
/** /**