mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-13 14:26:30 -04:00
cache clock_gettime/gettimeofday values in base
svn:r758
This commit is contained in:
parent
f04497e493
commit
45e6fb0dd2
@ -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.
|
||||
|
@ -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
46
event.c
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user