}
static int
-gettime(struct timeval *tp)
+gettime(struct event_base *base, struct timeval *tp)
{
+ if (base->tv_cache.tv_sec) {
+ *tp = base->tv_cache;
+ return (0);
+ }
+
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
struct timespec ts;
event_gotsig = 0;
detect_monotonic();
- gettime(&base->event_tv);
+ gettime(base, &base->event_tv);
min_heap_ctor(&base->timeheap);
TAILQ_INIT(&base->eventqueue);
return (1);
}
+ /* update last old time */
+ gettime(base, &base->event_tv);
+
+ /* clear time cache */
+ base->tv_cache.tv_sec = 0;
+
res = evsel->dispatch(base, evbase, tv_p);
if (res == -1)
return (-1);
+ gettime(base, &base->tv_cache);
timeout_process(base);
/* See if there is a timeout that we should report */
if (tv != NULL && (flags & event & EV_TIMEOUT)) {
- gettime(&now);
+ gettime(ev->ev_base, &now);
evutil_timersub(&ev->ev_timeout, &now, &res);
/* correctly remap to real time */
gettimeofday(&now, NULL);
event_queue_remove(base, ev, EVLIST_ACTIVE);
}
- gettime(&now);
+ gettime(base, &now);
evutil_timeradd(&now, tv, &ev->ev_timeout);
event_debug((
goto out;
}
- if (gettime(&now) == -1) {
+ if (gettime(base, &now) == -1) {
res = -1;
goto out;
}
return;
/* Check if time is running backwards */
- gettime(tv);
+ gettime(base, tv);
EVTHREAD_ACQUIRE_LOCK(base, EVTHREAD_WRITE, th_base_lock);
if (evutil_timercmp(tv, &base->event_tv, >=)) {
return;
}
- gettime(&now);
+ gettime(base, &now);
while ((ev = min_heap_top(&base->timeheap))) {
if (evutil_timercmp(&ev->ev_timeout, &now, >))
ev->ev_flags &= ~queue;
switch (queue) {
+ case EVLIST_INSERTED:
+ TAILQ_REMOVE(&base->eventqueue, ev, ev_next);
+ break;
case EVLIST_ACTIVE:
base->event_count_active--;
TAILQ_REMOVE(base->activequeues[ev->ev_pri],
ev, ev_active_next);
break;
- case EVLIST_SIGNAL:
- TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next);
- break;
case EVLIST_TIMEOUT:
min_heap_erase(&base->timeheap, ev);
break;
- case EVLIST_INSERTED:
- TAILQ_REMOVE(&base->eventqueue, ev, ev_next);
+ case EVLIST_SIGNAL:
+ TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next);
break;
default:
event_errx(1, "%s: unknown queue %x", __func__, queue);
ev->ev_flags |= queue;
switch (queue) {
+ case EVLIST_INSERTED:
+ TAILQ_INSERT_TAIL(&base->eventqueue, ev, ev_next);
+ break;
case EVLIST_ACTIVE:
base->event_count_active++;
TAILQ_INSERT_TAIL(base->activequeues[ev->ev_pri],
ev,ev_active_next);
break;
- case EVLIST_SIGNAL:
- TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next);
- break;
case EVLIST_TIMEOUT: {
min_heap_push(&base->timeheap, ev);
break;
}
- case EVLIST_INSERTED:
- TAILQ_INSERT_TAIL(&base->eventqueue, ev, ev_next);
+ case EVLIST_SIGNAL:
+ TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next);
break;
default:
event_errx(1, "%s: unknown queue %x", __func__, queue);
run_once(int num_pipes)
{
int *cp, i;
- static struct timeval ts, te;
+ static struct timeval ts, te, tv_timeout;
events = calloc(num_pipes, sizeof(struct event));
pipes = calloc(num_pipes * 2, sizeof(int));
}
}
+ /* measurements includes event setup */
+ gettimeofday(&ts, NULL);
+
+ /* provide a default timeout for events */
+ timerclear(&tv_timeout);
+ tv_timeout.tv_sec = 60;
+
for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
long fd = i < num_pipes - 1 ? cp[3] : -1;
event_set(&events[i], cp[0], EV_READ, read_cb, (void *) fd);
- event_add(&events[i], NULL);
+ event_add(&events[i], &tv_timeout);
}
fired = 0;
/* kick everything off with a single write */
write(pipes[1], "e", 1);
- gettimeofday(&ts, NULL);
event_dispatch();
gettimeofday(&te, NULL);