Rather than interrupting 10 times per second then checking

to see if there's anything to do, schedule the next alarm
based on the next required timeout.
This decreases the load when there are lots of relatively
idle ppp processes.

While I'm in there, handle the possibility that a timeout
makes the timer element go out of scope by grabbing the
enext pointer before executing the timer function.
This commit is contained in:
Brian Somers 1998-12-14 19:24:30 +00:00
parent c1b7af8ac3
commit 7e778f13d9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=41799
3 changed files with 45 additions and 48 deletions

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bundle.c,v 1.40 1998/10/29 23:47:10 brian Exp $
* $Id: bundle.c,v 1.41 1998/12/10 18:36:30 brian Exp $
*/
#include <sys/param.h>
@ -1659,7 +1659,7 @@ bundle_setsid(struct bundle *bundle, int holdsession)
log_Printf(LogPHASE, "%d -> %d: %s session control\n",
(int)orig, (int)getpid(),
holdsession ? "Passed" : "Dropped");
timer_InitService();
timer_InitService(0); /* Start the Timer Service */
break;
default:
close(fds[1]);

View File

@ -17,11 +17,12 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: timer.c,v 1.30 1998/06/20 01:36:38 brian Exp $
* $Id: timer.c,v 1.31 1998/06/27 14:18:11 brian Exp $
*
* TODO:
*/
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <sys/time.h>
@ -96,8 +97,8 @@ timer_Start(struct pppTimer * tp)
if (pt) {
pt->next = tp;
} else {
timer_InitService();
TimerList = tp;
timer_InitService(0); /* Start the Timer Service */
}
if (t)
t->rest -= tp->rest;
@ -143,7 +144,7 @@ StopTimerNoBlock(struct pppTimer * tp)
static void
TimerService(void)
{
struct pppTimer *tp, *exp, *wt;
struct pppTimer *tp, *exp, *next;
if (log_IsKept(LogTIMER)) {
static time_t t; /* Only show timers globally every second */
@ -153,43 +154,34 @@ TimerService(void)
timer_Show(LogTIMER, NULL);
t = n;
}
tp = TimerList;
if (tp) {
tp->rest--;
if (tp->rest == 0) {
tp->rest = 0;
/*
* Multiple timers may expires at once. Create list of expired timers.
*/
exp = NULL;
do {
tp->state = TIMER_EXPIRED;
wt = tp->next;
tp->enext = exp;
exp = tp;
tp = wt;
} while (tp && (tp->rest == 0));
TimerList = tp;
if (TimerList == NULL) /* No timers ? */
timer_TermService(); /* Terminate Timer Service */
/*
* Process all expired timers.
*/
while (exp) {
#ifdef notdef
timer_Stop(exp);
#endif
if (exp->func)
(*exp->func) (exp->arg);
/*
* Just Removing each item from expired list And exp->enext will be
* intialized at next expire in this funtion.
*/
exp = exp->enext;
}
/* Multiple timers might expire at once. Create a list of expired timers */
exp = NULL;
do {
tp->state = TIMER_EXPIRED;
next = tp->next;
tp->enext = exp;
exp = tp;
tp = next;
} while (tp && tp->rest == 0);
TimerList = tp;
if (TimerList != NULL) /* Any timers remaining ? */
timer_InitService(1); /* Restart the Timer Service */
else
timer_TermService(); /* Stop the Timer Service */
/* Process all expired timers */
while (exp) {
next = exp->enext;
exp->enext = NULL;
if (exp->func)
(*exp->func)(exp->arg);
exp = next;
}
}
}
@ -223,15 +215,20 @@ timer_Show(int LogLevel, struct prompt *prompt)
}
void
timer_InitService()
timer_InitService(int restart)
{
struct itimerval itimer;
sig_signal(SIGALRM, (void (*) (int)) TimerService);
itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0;
itimer.it_interval.tv_usec = itimer.it_value.tv_usec = TICKUNIT;
if (setitimer(ITIMER_REAL, &itimer, NULL) == -1)
log_Printf(LogERROR, "Unable to set itimer.\n");
if (TimerList) {
if (!restart)
sig_signal(SIGALRM, (void (*)(int))TimerService);
itimer.it_interval.tv_sec = 0;
itimer.it_interval.tv_usec = 0;
itimer.it_value.tv_sec = TimerList->rest / SECTICKS;
itimer.it_value.tv_usec = (TimerList->rest % SECTICKS) * TICKUNIT;
if (setitimer(ITIMER_REAL, &itimer, NULL) == -1)
log_Printf(LogERROR, "Unable to set itimer (%s)\n", sys_errlist[errno]);
}
}
void
@ -242,6 +239,6 @@ timer_TermService(void)
itimer.it_interval.tv_usec = itimer.it_interval.tv_sec = 0;
itimer.it_value.tv_usec = itimer.it_value.tv_sec = 0;
if (setitimer(ITIMER_REAL, &itimer, NULL) == -1)
log_Printf(LogERROR, "Unable to set itimer.\n");
log_Printf(LogERROR, "Unable to set itimer (%s)\n", sys_errlist[errno]);
sig_signal(SIGALRM, SIG_IGN);
}

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: timer.h,v 1.6 1998/05/21 21:48:49 brian Exp $
* $Id: timer.h,v 1.7 1998/06/20 01:36:38 brian Exp $
*
* TODO:
*/
@ -42,6 +42,6 @@ struct prompt;
extern void timer_Start(struct pppTimer *);
extern void timer_Stop(struct pppTimer *);
extern void timer_InitService(void);
extern void timer_InitService(int);
extern void timer_TermService(void);
extern void timer_Show(int LogLevel, struct prompt *);