From bfdf56c22e9b8d30d08bf3b59b68fd2993f0c4ca Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Sat, 3 May 2008 18:27:24 +0000 Subject: [PATCH] from trunk: cache clock_gettime/gettimeofday values in base svn:r759 --- ChangeLog | 1 + event-internal.h | 2 ++ event.c | 46 +++++++++++++++++++++++++++++----------------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0f3f1e8b..442d1a25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ Changes in 1.4.4-stable: o fix a bug in bufferevent read water marks and add a test for them o introduce bufferevent_setcb and bufferevent_setfd to allow better manipulation of bufferevents o use libevent's internal timercmp on all platforms, to avoid bugs on old platforms where timercmp(a,b,<=) is buggy. + o reduce system calls for getting current time by caching it. Changes in 1.4.3-stable: diff --git a/event-internal.h b/event-internal.h index 19b7a547..7485f217 100644 --- a/event-internal.h +++ b/event-internal.h @@ -66,6 +66,8 @@ struct event_base { struct timeval event_tv; struct min_heap timeheap; + + struct timeval tv_cache; }; /* Internal use only: Functions that might be missing from */ diff --git a/event.c b/event.c index e96c1b6a..5efaaee0 100644 --- a/event.c +++ b/event.c @@ -137,8 +137,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; @@ -179,7 +184,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); @@ -497,10 +502,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); @@ -668,7 +680,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); @@ -720,7 +732,7 @@ event_add(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(( @@ -820,7 +832,7 @@ timeout_next(struct event_base *base, struct timeval **tv_p) return (0); } - if (gettime(&now) == -1) + if (gettime(base, &now) == -1) return (-1); if (evutil_timercmp(&ev->ev_timeout, &now, <=)) { @@ -854,7 +866,7 @@ timeout_correct(struct event_base *base, struct timeval *tv) return; /* Check if time is running backwards */ - gettime(tv); + gettime(base, tv); if (evutil_timercmp(tv, &base->event_tv, >=)) { base->event_tv = *tv; return; @@ -885,7 +897,7 @@ timeout_process(struct event_base *base) if (min_heap_empty(&base->timeheap)) return; - gettime(&now); + gettime(base, &now); while ((ev = min_heap_top(&base->timeheap))) { if (evutil_timercmp(&ev->ev_timeout, &now, >)) @@ -912,19 +924,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); @@ -948,20 +960,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);