cache clock_gettime/gettimeofday values in base

svn:r758
This commit is contained in:
Niels Provos 2008-05-03 18:23:44 +00:00
parent f04497e493
commit 45e6fb0dd2
4 changed files with 41 additions and 20 deletions

View File

@ -85,6 +85,7 @@ Changes in current version:
o switch internal uses of event_set over to use event_assign.
o introduce evbuffer_contiguous_space() api that tells a user how much data is available in the first buffer chain
o introduce evbuffer_reserve_space() and evbuffer_commit_space() to make processing in filters more efficient.
o reduce system calls for getting current time by caching it.
Changes in 1.4.0:
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.

View File

@ -68,6 +68,8 @@ struct event_base {
struct min_heap timeheap;
struct timeval tv_cache;
/* threading support */
unsigned long th_owner_id;
unsigned long (*th_get_id)(void);

46
event.c
View File

@ -148,8 +148,13 @@ detect_monotonic(void)
}
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;
@ -190,7 +195,7 @@ event_base_new(void)
event_gotsig = 0;
detect_monotonic();
gettime(&base->event_tv);
gettime(base, &base->event_tv);
min_heap_ctor(&base->timeheap);
TAILQ_INIT(&base->eventqueue);
@ -532,10 +537,17 @@ event_base_loop(struct event_base *base, int flags)
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);
@ -736,7 +748,7 @@ event_pending(struct event *ev, short event, struct timeval *tv)
/* 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);
@ -803,7 +815,7 @@ event_add_internal(struct event *ev, struct timeval *tv)
event_queue_remove(base, ev, EVLIST_ACTIVE);
}
gettime(&now);
gettime(base, &now);
evutil_timeradd(&now, tv, &ev->ev_timeout);
event_debug((
@ -941,7 +953,7 @@ timeout_next(struct event_base *base, struct timeval **tv_p)
goto out;
}
if (gettime(&now) == -1) {
if (gettime(base, &now) == -1) {
res = -1;
goto out;
}
@ -979,7 +991,7 @@ timeout_correct(struct event_base *base, struct timeval *tv)
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, >=)) {
@ -1017,7 +1029,7 @@ timeout_process(struct event_base *base)
return;
}
gettime(&now);
gettime(base, &now);
while ((ev = min_heap_top(&base->timeheap))) {
if (evutil_timercmp(&ev->ev_timeout, &now, >))
@ -1045,19 +1057,19 @@ event_queue_remove(struct event_base *base, struct event *ev, int queue)
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);
@ -1081,20 +1093,20 @@ event_queue_insert(struct event_base *base, struct event *ev, int 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);

View File

@ -77,7 +77,7 @@ static struct timeval *
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));
@ -94,10 +94,17 @@ run_once(int num_pipes)
}
}
/* 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;
@ -105,7 +112,6 @@ run_once(int num_pipes)
/* kick everything off with a single write */
write(pipes[1], "e", 1);
gettimeofday(&ts, NULL);
event_dispatch();
gettimeofday(&te, NULL);