mirror of
https://github.com/troglobit/libuev.git
synced 2026-10-28 11:50:42 +00:00
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:
1 parent
d9f078a119
commit
0de9cb6321
3 files changed
+91
-117
No files matched your search
@@ -1,3 +1,4 @@
|
|||||||
|
bench
|
||||||
test
|
test
|
||||||
.*.d
|
.*.d
|
||||||
*.o
|
*.o
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in new issue
Block a user