From 6da7c87a77ecfd9ccce36f96b4ccd20e1b9cccf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tatuya=20JINMEI=20=E7=A5=9E=E6=98=8E=E9=81=94=E5=93=89?= Date: Sat, 25 Oct 2003 00:09:14 +0000 Subject: [PATCH] 1527. [cleanup] Reduce the number of gettimeofday() calls without losing necessary timer granularity. (reviewed by marka and Kurt) --- CHANGES | 3 ++- bin/named/client.c | 6 ++---- lib/isc/include/isc/task.h | 20 +++++++++++++++++--- lib/isc/task.c | 16 +++++++++++++++- lib/isc/unix/app.c | 32 ++++++++++++++++++++++++++------ 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index f38401df19..7eef922d39 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ 1528. [placeholder] -1527. [placeholder] +1527. [cleanup] Reduce the number of gettimeofday() calls without + losing necessary timer granularity. 1526. [placeholder] diff --git a/bin/named/client.c b/bin/named/client.c index 9ac61d7772..5c14abf322 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.216 2003/07/04 04:38:54 marka Exp $ */ +/* $Id: client.c,v 1.217 2003/10/25 00:09:13 jinmei Exp $ */ #include @@ -1129,8 +1129,6 @@ client_request(isc_task_t *task, isc_event_t *event) { REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(task == client->task); - UNUSED(task); - INSIST(client->recursionquota == NULL); INSIST(client->state == @@ -1174,7 +1172,7 @@ client_request(isc_task_t *task, isc_event_t *event) { goto cleanup; client->state = client->newstate = NS_CLIENTSTATE_WORKING; - isc_stdtime_get(&client->requesttime); + isc_task_getcurrenttime(task, &client->requesttime); client->now = client->requesttime; if (result != ISC_R_SUCCESS) { diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index 78fd9845b0..33d828ad5a 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: task.h,v 1.49 2001/02/13 04:11:44 gson Exp $ */ +/* $Id: task.h,v 1.50 2003/10/25 00:09:14 jinmei Exp $ */ #ifndef ISC_TASK_H #define ISC_TASK_H 1 @@ -58,9 +58,10 @@ *** Imports. ***/ -#include -#include #include +#include +#include +#include #define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0) #define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1) @@ -518,6 +519,19 @@ isc_task_endexclusive(isc_task_t *task); * exclusive access by calling isc_task_spl(). */ +void +isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t); +/* + * Provide the most recent timestamp on the task. The timestamp is considered + * as the "current time" in the second-order granularity. + * + * Requires: + * 'task' is a valid task. + * 't' is a valid non NULL pointer. + * + * Ensures: + * '*t' has the "current time". + */ /***** ***** Task Manager. diff --git a/lib/isc/task.c b/lib/isc/task.c index dba0f9fdad..4d8431915b 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: task.c,v 1.88 2002/07/19 03:39:43 marka Exp $ */ +/* $Id: task.c,v 1.89 2003/10/25 00:09:13 jinmei Exp $ */ /* * Principal Author: Bob Halley @@ -82,6 +82,7 @@ struct isc_task { isc_eventlist_t on_shutdown; unsigned int quantum; unsigned int flags; + isc_stdtime_t now; #ifdef ISC_TASK_NAMES char name[16]; void * tag; @@ -196,6 +197,7 @@ isc_task_create(isc_taskmgr_t *manager, unsigned int quantum, INIT_LIST(task->on_shutdown); task->quantum = quantum; task->flags = 0; + task->now = 0; #ifdef ISC_TASK_NAMES memset(task->name, 0, sizeof(task->name)); task->tag = NULL; @@ -717,6 +719,17 @@ isc_task_gettag(isc_task_t *task) { return (task->tag); } +void +isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) { + REQUIRE(VALID_TASK(task)); + REQUIRE(t != NULL); + + LOCK(&task->lock); + + *t = task->now; + + UNLOCK(&task->lock); +} /*** *** Task Manager. @@ -838,6 +851,7 @@ dispatch(isc_taskmgr_t *manager) { task->state = task_state_running; XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_RUNNING, "running")); + isc_stdtime_get(&task->now); do { if (!EMPTY(task->events)) { event = HEAD(task->events); diff --git a/lib/isc/unix/app.c b/lib/isc/unix/app.c index 9a4dd0a902..ef8b581e92 100644 --- a/lib/isc/unix/app.c +++ b/lib/isc/unix/app.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: app.c,v 1.48 2002/05/10 06:41:54 marka Exp $ */ +/* $Id: app.c,v 1.49 2003/10/25 00:09:14 jinmei Exp $ */ #include @@ -304,12 +304,14 @@ evloop() { fd_set readfds, writefds; int maxfd; isc_boolean_t readytasks; + isc_boolean_t call_timer_dispatch = ISC_FALSE; readytasks = isc__taskmgr_ready(); if (readytasks) { tv.tv_sec = 0; tv.tv_usec = 0; tvp = &tv; + call_timer_dispatch = ISC_TRUE; } else { result = isc__timermgr_nextevent(&when); if (result != ISC_R_SUCCESS) @@ -319,6 +321,8 @@ evloop() { TIME_NOW(&now); us = isc_time_microdiff(&when, &now); + if (us == 0) + call_timer_dispatch = ISC_TRUE; tv.tv_sec = us / 1000000; tv.tv_usec = us % 1000000; tvp = &tv; @@ -328,7 +332,23 @@ evloop() { isc__socketmgr_getfdsets(&readfds, &writefds, &maxfd); n = select(maxfd, &readfds, &writefds, NULL, tvp); - isc__timermgr_dispatch(); + if (n == 0 || call_timer_dispatch) { + /* + * We call isc__timermgr_dispatch() only when + * necessary, in order to reduce overhead. If the + * select() call indicates a timeout, we need the + * dispatch. Even if not, if we set the 0-timeout + * for the select() call, we need to check the timer + * events. In the 'readytasks' case, there may be no + * timeout event actually, but there is no other way + * to reduce the overhead. + * Note that we do not have to worry about the case + * where a new timer is inserted during the select() + * call, since this loop only runs in the non-thread + * mode. + */ + isc__timermgr_dispatch(); + } if (n > 0) (void)isc__socketmgr_dispatch(&readfds, &writefds, maxfd); @@ -367,16 +387,16 @@ static isc_boolean_t signalled = ISC_FALSE; isc_result_t isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) { isc_result_t result; - + UNUSED(cp); UNUSED(mp); - + INSIST(!in_recursive_evloop); in_recursive_evloop = ISC_TRUE; INSIST(*mp == 1); /* Mutex must be locked on entry. */ --*mp; - + result = evloop(); if (result == ISC_R_RELOAD) want_reload = ISC_TRUE; @@ -394,7 +414,7 @@ isc_result_t isc__nothread_signal_hack(isc_condition_t *cp) { UNUSED(cp); - + INSIST(in_recursive_evloop); want_shutdown = ISC_TRUE;