mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
from trunk: cache clock_gettime/gettimeofday values in base
svn:r759
This commit is contained in:
parent
2a69a5ea9a
commit
bfdf56c22e
@ -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:
|
||||
|
@ -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 <sys/queue.h> */
|
||||
|
46
event.c
46
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user