timer.c revision 6060
1145479Smp/*
259243Sobrien *		PPP Timer Processing Module
359243Sobrien *
459243Sobrien *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
559243Sobrien *
659243Sobrien *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
759243Sobrien *
859243Sobrien * Redistribution and use in source and binary forms are permitted
959243Sobrien * provided that the above copyright notice and this paragraph are
1059243Sobrien * duplicated in all such forms and that any documentation,
1159243Sobrien * advertising materials, and other materials related to such
1259243Sobrien * distribution and use acknowledge that the software was developed
1359243Sobrien * by the Internet Initiative Japan, Inc.  The name of the
1459243Sobrien * IIJ may not be used to endorse or promote products derived
1559243Sobrien * from this software without specific prior written permission.
1659243Sobrien * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17100616Smp * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1859243Sobrien * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1959243Sobrien *
2059243Sobrien * $Id:$
2159243Sobrien *
2259243Sobrien *  TODO:
2359243Sobrien */
2459243Sobrien#include "defs.h"
2559243Sobrien#include <sys/time.h>
2659243Sobrien#include <signal.h>
2759243Sobrien#include "timeout.h"
2859243Sobrien
2959243Sobrienvoid
3059243SobrienStartTimer(tp)
3159243Sobrienstruct pppTimer *tp;
3259243Sobrien{
3359243Sobrien  struct pppTimer *t, *pt;
3459243Sobrien  u_long ticks = 0;
35145479Smp
3659243Sobrien  if (tp->state == TIMER_RUNNING) {
3759243Sobrien    StopTimer(tp);
3859243Sobrien  }
3959243Sobrien  if (tp->load == 0) {
4059243Sobrien#ifdef DEBUG
4159243Sobrien    logprintf("timer %x has 0 load!\n", tp);
4259243Sobrien#endif
43145479Smp    return;
4459243Sobrien  }
4559243Sobrien  pt = NULL;
4659243Sobrien  for (t = TimerList; t; t = t->next) {
4759243Sobrien#ifdef DEBUG
4859243Sobrien    logprintf("%x(%d):  ticks: %d, rest: %d\n", t, t->state, ticks, t->rest);
4959243Sobrien#endif
5059243Sobrien    if (ticks + t->rest >= tp->load)
5159243Sobrien      break;
52145479Smp    ticks += t->rest;
5359243Sobrien    pt = t;
54145479Smp  }
5559243Sobrien
5659243Sobrien  tp->state = TIMER_RUNNING;
5759243Sobrien  tp->rest = tp->load - ticks;
5859243Sobrien#ifdef DEBUG
5959243Sobrien  logprintf("Inserting %x before %x, rest = %d\n", tp, t, tp->rest);
6059243Sobrien#endif
6159243Sobrien  /* Insert given *tp just before *t */
6259243Sobrien  tp->next = t;
6359243Sobrien  if (pt) {
6459243Sobrien    pt->next = tp;
6559243Sobrien  } else
6659243Sobrien    TimerList = tp;
6759243Sobrien  if (t)
6859243Sobrien    t->rest -= tp->rest;
6959243Sobrien}
7059243Sobrien
7159243Sobrienvoid
7259243SobrienStopTimer(tp)
7359243Sobrienstruct pppTimer *tp;
7459243Sobrien{
7559243Sobrien  struct pppTimer *t, *pt;
76145479Smp
7759243Sobrien  if (tp->state != TIMER_RUNNING) {
7859243Sobrien    tp->next = NULL;
7959243Sobrien    return;
8059243Sobrien  }
8159243Sobrien
8259243Sobrien#ifdef DEBUG
8359243Sobrien  logprintf("StopTimer: %x, next = %x\n", tp, tp->next);
8459243Sobrien#endif
85145479Smp  pt = NULL;
8659243Sobrien  for (t = TimerList; t != tp; t = t->next)
8759243Sobrien    pt = t;
8859243Sobrien  if (t) {
8959243Sobrien    if (pt)
9059243Sobrien      pt->next = t->next;
9159243Sobrien    else
9259243Sobrien      TimerList = t->next;
9359243Sobrien    if (t->next)
9459243Sobrien      t->next->rest += tp->rest;
9559243Sobrien  } else
9659243Sobrien    fprintf(stderr, "Oops, timer not found!!\n");
9759243Sobrien  tp->next = NULL;
9859243Sobrien  tp->state = TIMER_STOPPED;
9959243Sobrien}
10059243Sobrien
10159243Sobrienvoid
10259243SobrienTimerService()
10359243Sobrien{
10459243Sobrien  struct pppTimer *tp, *exp, *wt;
10559243Sobrien
106145479Smp  if (tp = TimerList) {
10759243Sobrien    tp->rest--;
10859243Sobrien    if (tp->rest == 0) {
109145479Smp      /*
11059243Sobrien       * Multiple timers may expires at once. Create list of expired timers.
11159243Sobrien       */
11259243Sobrien      exp = NULL;
11359243Sobrien      do {
114145479Smp	tp->state = TIMER_EXPIRED;
115145479Smp	wt = tp->next;
11659243Sobrien	tp->enext = exp;
117145479Smp	exp = tp;
11859243Sobrien#ifdef DEBUG
119145479Smp	logprintf("Add %x to exp\n", tp);
120145479Smp#endif
121145479Smp	tp = wt;
122145479Smp      } while (tp && (tp->rest == 0));
123145479Smp
124145479Smp      TimerList = tp;
125145479Smp#ifdef DEBUG
126145479Smp      logprintf("TimerService: next is %x(%d)\n",
127145479Smp		TimerList, TimerList? TimerList->rest : 0);
128145479Smp#endif
129145479Smp      /*
130145479Smp       * Process all expired timers.
131145479Smp       */
132145479Smp      while (exp) {
133145479Smp#ifdef notdef
134145479Smp	StopTimer(exp);
135145479Smp#endif
136145479Smp	if (exp->func)
137145479Smp	  (*exp->func)(exp->arg);
138145479Smp	exp = exp->enext;
139145479Smp      }
140145479Smp    }
141145479Smp  }
14259243Sobrien}
143145479Smp
14459243Sobrienvoid
14559243SobrienShowTimers()
14659243Sobrien{
14759243Sobrien  struct pppTimer *pt;
14859243Sobrien
14959243Sobrien  for (pt = TimerList; pt; pt = pt->next)
150145479Smp    fprintf(stderr, "%x: load = %d, rest = %d\r\n", pt, pt->load, pt->rest);
15159243Sobrien}
152145479Smp