From a229b3e4ebe09ae41a6c4a7f84580406abd2af7d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 5 Mar 2016 10:57:24 -0500 Subject: [PATCH] Small optimization: remove needless code from internal sched() calls When we call timeout_sched() internally, sometimes we can be sure that the timeout is in the future. Always, we can be sure that the timeout has its expires field and its timeouts field set correctly, and that it is not currently pending. (Do not merge this patch without benchmarking to see if it makes a measurable difference.) --- timeout.c | 58 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/timeout.c b/timeout.c index e78f57d..b92c27a 100644 --- a/timeout.c +++ b/timeout.c @@ -320,10 +320,10 @@ static inline int timeout_slot(int wheel, timeout_t expires) { return WHEEL_MASK & ((expires >> (wheel * WHEEL_BIT)) - !!wheel); } /* timeout_slot() */ +static void timeouts_sched_nopending(struct timeouts *T, struct timeout *to); +static void timeouts_sched_future_nopending(struct timeouts *T, struct timeout *to); static void timeouts_sched(struct timeouts *T, struct timeout *to, timeout_t expires) { - timeout_t rem; - int wheel, slot; timeouts_del(T, to); @@ -331,26 +331,42 @@ static void timeouts_sched(struct timeouts *T, struct timeout *to, timeout_t exp TO_SET_TIMEOUTS(to, T); - if (expires > T->curtime) { - rem = timeout_rem(T, to); - - /* rem is nonzero since: - * rem == timeout_rem(T,to), - * == to->expires - T->curtime - * and above we have expires > T->curtime. - */ - wheel = timeout_wheel(rem); - slot = timeout_slot(wheel, to->expires); - - to->pending = &T->wheel[wheel][slot]; - TAILQ_INSERT_TAIL(to->pending, to, tqe); + timeouts_sched_nopending(T, to); +} /* timeouts_sched() */ - T->pending[wheel] |= WHEEL_C(1) << slot; - } else { +/* As 'timeouts_sched_future_nopending', but do not require that to->expires + * is in the future. */ +static void timeouts_sched_nopending(struct timeouts *T, struct timeout *to) { + if (to->expires > T->curtime) { + timeouts_sched_future_nopending(T, to); + } else { to->pending = &T->expired; TAILQ_INSERT_TAIL(to->pending, to, tqe); - } -} /* timeouts_sched() */ + } +} /* timeouts_sched_nopending() */ + +/* Insert 'to' into 'T'. Requres that to->expires is set, and set some time +* in the future. Requires that to is not pending or expired. Requires that +* TO_SET_TIMEOUTS has been set. */ +static void timeouts_sched_future_nopending(struct timeouts *T, struct timeout *to) { + timeout_t rem; + int wheel, slot; + + rem = timeout_rem(T, to); + + /* rem is nonzero since: + * rem == timeout_rem(T,to), + * == to->expires - T->curtime + * and above we have expires > T->curtime. + */ + wheel = timeout_wheel(rem); + slot = timeout_slot(wheel, to->expires); + + to->pending = &T->wheel[wheel][slot]; + TAILQ_INSERT_TAIL(to->pending, to, tqe); + + T->pending[wheel] |= WHEEL_C(1) << slot; +} /* timeouts_sched_future_nopending() */ #ifndef TIMEOUT_DISABLE_INTERVALS @@ -367,7 +383,7 @@ static void timeouts_readd(struct timeouts *T, struct timeout *to) { to->expires = T->curtime + (to->interval - r); } - timeouts_sched(T, to, to->expires); + timeouts_sched_future_nopending(T, to); } /* timeouts_readd() */ #endif @@ -454,7 +470,7 @@ TIMEOUT_PUBLIC void timeouts_update(struct timeouts *T, abstime_t curtime) { TAILQ_REMOVE(&todo, to, tqe); to->pending = NULL; - timeouts_sched(T, to, to->expires); + timeouts_sched_nopending(T, to); } return;