diff --git a/httperf/src/timer.c b/httperf/src/timer.c index 9c9643e..44db8b4 100755 --- a/httperf/src/timer.c +++ b/httperf/src/timer.c @@ -1,36 +1,34 @@ /* - httperf -- a tool for measuring web server performance - Copyright 2000-2007 Hewlett-Packard Company and Contributors listed in - AUTHORS file. Originally contributed by David Mosberger-Tang - - This file is part of httperf, a web server performance measurment - tool. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - In addition, as a special exception, the copyright holders give - permission to link the code of this work with the OpenSSL project's - "OpenSSL" library (or with modified versions of it that use the same - license as the "OpenSSL" library), and distribute linked combinations - including the two. You must obey the GNU General Public License in - all respects for all of the code used other than "OpenSSL". If you - modify this file, you may extend this exception to your version of the - file, but you are not obligated to do so. If you do not wish to do - so, delete this exception statement from your version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA -*/ + * httperf -- a tool for measuring web server performance Copyright 2000-2007 + * Hewlett-Packard Company and Contributors listed in AUTHORS file. Originally + * contributed by David Mosberger-Tang + * + * This file is part of httperf, a web server performance measurment tool. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * In addition, as a special exception, the copyright holders give permission + * to link the code of this work with the OpenSSL project's "OpenSSL" library + * (or with modified versions of it that use the same license as the "OpenSSL" + * library), and distribute linked combinations including the two. You must + * obey the GNU General Public License in all respects for all of the code + * used other than "OpenSSL". If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include @@ -46,171 +44,165 @@ #define WHEEL_SIZE 4096 #if 1 -static Time now; +static Time now; #endif -static Time next_tick; -static Timer *timer_free_list = 0; -static Timer *t_curr = 0; +static Time next_tick; +static Timer *timer_free_list = 0; +static Timer *t_curr = 0; -/* What a wheel is made of, no? */ +/* + * What a wheel is made of, no? + */ static Timer_Queue wheel[WHEEL_SIZE], *curr = 0; static void -done (Timer *t) +done(Timer * t) { - t->q.next = timer_free_list; - t->q.prev = 0; - timer_free_list = t; + t->q.next = timer_free_list; + t->q.prev = 0; + timer_free_list = t; } Time -timer_now_forced (void) +timer_now_forced(void) { - struct timeval tv; + struct timeval tv; - gettimeofday (&tv, 0); - return tv.tv_sec + tv.tv_usec*1e-6; + gettimeofday(&tv, 0); + return tv.tv_sec + tv.tv_usec * 1e-6; } Time -timer_now (void) +timer_now(void) { - if(param.use_timer_cache) - return now; - else - return timer_now_forced (); + if (param.use_timer_cache) + return now; + else + return timer_now_forced(); } void -timer_init (void) +timer_init(void) { - now = timer_now_forced (); - memset (wheel, 0, sizeof (wheel)); - next_tick = timer_now () + TIMER_INTERVAL; - curr = wheel; -} - -void -timer_tick (void) -{ - Timer *t, *t_next; - - assert (!t_curr); - - now = timer_now_forced (); - - while (timer_now () >= next_tick) - { - for (t = curr->next; t && t->delta == 0; t = t_next) - { - t_curr = t; - (*t->func) (t, t->arg); - t_next = t->q.next; - done (t); - } - t_curr = 0; - curr->next = t; - if (t) - { - t->q.prev = (Timer *) curr; - --t->delta; - } - next_tick += TIMER_INTERVAL; - if (++curr >= wheel + WHEEL_SIZE) + now = timer_now_forced(); + memset(wheel, 0, sizeof(wheel)); + next_tick = timer_now() + TIMER_INTERVAL; curr = wheel; - } -} - -Timer* -timer_schedule (Timer_Callback timeout, Any_Type arg, Time delay) -{ - Timer_Queue *spoke; - Timer *t, *p; - u_long ticks; - u_long delta; - Time behind; - - if (timer_free_list) - { - t = timer_free_list; - timer_free_list = t->q.next; - } - else - { - t = malloc (sizeof (*t)); - if (!t) - { - fprintf (stderr, "%s.timer_schedule: %s\n", - prog_name, strerror (errno)); - return 0; - } - } - memset (t, 0, sizeof (*t)); - t->func = timeout; - t->arg = arg; - - behind = (timer_now () - next_tick); - if (behind > 0.0) - delay += behind; - - if (delay < 0.0) - ticks = 1; - else - { - ticks = (delay + TIMER_INTERVAL / 2.0) * (1.0 / TIMER_INTERVAL); - if (!ticks) - ticks = 1; /* minimum delay is a tick */ - } - - spoke = curr + (ticks % WHEEL_SIZE); - if (spoke >= wheel + WHEEL_SIZE) - spoke -= WHEEL_SIZE; - - delta = ticks / WHEEL_SIZE; - p = (Timer *) spoke; - while (p->q.next && delta > p->q.next->delta) - { - delta -= p->q.next->delta; - p = p->q.next; - } - t->q.next = p->q.next; - t->q.prev = p; - p->q.next = t; - t->delta = delta; - if (t->q.next) - { - t->q.next->q.prev = t; - t->q.next->delta -= delta; - } - - if (DBG > 2) - fprintf (stderr, "timer_schedule: t=%p, delay=%gs, arg=%lx\n", - t, delay, arg.l); - - return t; } void -timer_cancel (Timer *t) +timer_tick(void) { - if (DBG > 2) - fprintf (stderr, "timer_cancel: t=%p\n", t); + Timer *t, *t_next; - assert (t->q.prev); + assert(!t_curr); - /* A module MUST NOT call timer_cancel() for a timer that is - currently being processed (whose timeout has expired). */ - if (t_curr == t) - { - fprintf (stderr, "timer_cancel() called on currently active timer!\n"); - return; - } + now = timer_now_forced(); - if (t->q.next) - { - t->q.next->delta += t->delta; - t->q.next->q.prev = t->q.prev; - } - t->q.prev->q.next = t->q.next; - done (t); + while (timer_now() >= next_tick) { + for (t = curr->next; t && t->delta == 0; t = t_next) { + t_curr = t; + (*t->func) (t, t->arg); + t_next = t->q.next; + done(t); + } + t_curr = 0; + curr->next = t; + if (t) { + t->q.prev = (Timer *) curr; + --t->delta; + } + next_tick += TIMER_INTERVAL; + if (++curr >= wheel + WHEEL_SIZE) + curr = wheel; + } +} + +Timer * +timer_schedule(Timer_Callback timeout, Any_Type arg, Time delay) +{ + Timer_Queue *spoke; + Timer *t, *p; + u_long ticks; + u_long delta; + Time behind; + + if (timer_free_list) { + t = timer_free_list; + timer_free_list = t->q.next; + } else { + t = malloc(sizeof(*t)); + if (!t) { + fprintf(stderr, "%s.timer_schedule: %s\n", + prog_name, strerror(errno)); + return 0; + } + } + memset(t, 0, sizeof(*t)); + t->func = timeout; + t->arg = arg; + + behind = (timer_now() - next_tick); + if (behind > 0.0) + delay += behind; + + if (delay < 0.0) + ticks = 1; + else { + ticks = + (delay + TIMER_INTERVAL / 2.0) * (1.0 / TIMER_INTERVAL); + if (!ticks) + ticks = 1; /* minimum delay is a tick */ + } + + spoke = curr + (ticks % WHEEL_SIZE); + if (spoke >= wheel + WHEEL_SIZE) + spoke -= WHEEL_SIZE; + + delta = ticks / WHEEL_SIZE; + p = (Timer *) spoke; + while (p->q.next && delta > p->q.next->delta) { + delta -= p->q.next->delta; + p = p->q.next; + } + t->q.next = p->q.next; + t->q.prev = p; + p->q.next = t; + t->delta = delta; + if (t->q.next) { + t->q.next->q.prev = t; + t->q.next->delta -= delta; + } + + if (DBG > 2) + fprintf(stderr, "timer_schedule: t=%p, delay=%gs, arg=%lx\n", + t, delay, arg.l); + + return t; +} + +void +timer_cancel(Timer * t) +{ + if (DBG > 2) + fprintf(stderr, "timer_cancel: t=%p\n", t); + + assert(t->q.prev); + + /* + * A module MUST NOT call timer_cancel() for a timer that is currently + * being processed (whose timeout has expired). + */ + if (t_curr == t) { + fprintf(stderr, + "timer_cancel() called on currently active timer!\n"); + return; + } + + if (t->q.next) { + t->q.next->delta += t->delta; + t->q.next->q.prev = t->q.prev; + } + t->q.prev->q.next = t->q.next; + done(t); }