timer.c revision 6059
1125665Sache/*
221308Sache *		PPP Timer Processing Module
321308Sache *
421308Sache *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5157188Sache *
621308Sache *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
721308Sache *
821308Sache * Redistribution and use in source and binary forms are permitted
921308Sache * provided that the above copyright notice and this paragraph are
1021308Sache * duplicated in all such forms and that any documentation,
1121308Sache * advertising materials, and other materials related to such
1258310Sache * distribution and use acknowledge that the software was developed
1321308Sache * by the Internet Initiative Japan, Inc.  The name of the
1421308Sache * IIJ may not be used to endorse or promote products derived
1521308Sache * from this software without specific prior written permission.
1621308Sache * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1721308Sache * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1821308Sache * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1921308Sache *
2021308Sache * $Id:$
2121308Sache *
2221308Sache *  TODO:
2358310Sache */
2421308Sache#include "defs.h"
2521308Sache#include <sys/time.h>
2621308Sache#include <signal.h>
2721308Sache#include "timeout.h"
2821308Sache
2921308Sachevoid
3021308SacheStartTimer(tp)
3121308Sachestruct pppTimer *tp;
3221308Sache{
3321308Sache  struct pppTimer *t, *pt;
3421308Sache  u_long ticks = 0;
3521308Sache
3621308Sache  if (tp->state == TIMER_RUNNING) {
3721308Sache    StopTimer(tp);
3821308Sache  }
3921308Sache  if (tp->load == 0) {
4021308Sache#ifdef DEBUG
4121308Sache    logprintf("timer %x has 0 load!\n", tp);
4221308Sache#endif
4321308Sache    return;
4421308Sache  }
4521308Sache  pt = NULL;
4621308Sache  for (t = TimerList; t; t = t->next) {
4721308Sache#ifdef DEBUG
4821308Sache    logprintf("%x(%d):  ticks: %d, rest: %d\n", t, t->state, ticks, t->rest);
4921308Sache#endif
5021308Sache    if (ticks + t->rest >= tp->load)
5121308Sache      break;
5221308Sache    ticks += t->rest;
5321308Sache    pt = t;
5421308Sache  }
55119610Sache
56119610Sache  tp->state = TIMER_RUNNING;
5721308Sache  tp->rest = tp->load - ticks;
5821308Sache#ifdef DEBUG
5921308Sache  logprintf("Inserting %x before %x, rest = %d\n", tp, t, tp->rest);
6058310Sache#endif
6158310Sache  /* Insert given *tp just before *t */
6258310Sache  tp->next = t;
6321308Sache  if (pt) {
6421308Sache    pt->next = tp;
6521308Sache  } else
6621308Sache    TimerList = tp;
67136759Speter  if (t)
68136759Speter    t->rest -= tp->rest;
6921308Sache}
7021308Sache
7121308Sachevoid
7221308SacheStopTimer(tp)
73119610Sachestruct pppTimer *tp;
7421308Sache{
7521308Sache  struct pppTimer *t, *pt;
7621308Sache
7721308Sache  if (tp->state != TIMER_RUNNING) {
7821308Sache    tp->next = NULL;
7921308Sache    return;
8021308Sache  }
8121308Sache
8221308Sache#ifdef DEBUG
8321308Sache  logprintf("StopTimer: %x, next = %x\n", tp, tp->next);
8421308Sache#endif
8521308Sache  pt = NULL;
8621308Sache  for (t = TimerList; t != tp; t = t->next)
8721308Sache    pt = t;
8821308Sache  if (t) {
8921308Sache    if (pt)
9021308Sache      pt->next = t->next;
9121308Sache    else
92119610Sache      TimerList = t->next;
93119610Sache    if (t->next)
94157188Sache      t->next->rest += tp->rest;
95119610Sache  } else
9621308Sache    fprintf(stderr, "Oops, timer not found!!\n");
97119610Sache  tp->next = NULL;
9821308Sache  tp->state = TIMER_STOPPED;
9921308Sache}
10021308Sache
10121308Sachevoid
10221308SacheTimerService()
10321308Sache{
10421308Sache  struct pppTimer *tp, *exp, *wt;
10575406Sache
10621308Sache  if (tp = TimerList) {
10721308Sache    tp->rest--;
108119610Sache    if (tp->rest == 0) {
10921308Sache      /*
110119610Sache       * Multiple timers may expires at once. Create list of expired timers.
111119610Sache       */
112157188Sache      exp = NULL;
113165675Sache      do {
114165675Sache	tp->state = TIMER_EXPIRED;
115157188Sache	wt = tp->next;
116119610Sache	tp->enext = exp;
11721308Sache	exp = tp;
118157188Sache#ifdef DEBUG
119157188Sache	logprintf("Add %x to exp\n", tp);
120157188Sache#endif
121165675Sache	tp = wt;
122165675Sache      } while (tp && (tp->rest == 0));
123157188Sache
124157188Sache      TimerList = tp;
125157188Sache#ifdef DEBUG
126157188Sache      logprintf("TimerService: next is %x(%d)\n",
127157188Sache		TimerList, TimerList? TimerList->rest : 0);
128157188Sache#endif
129157188Sache      /*
130157188Sache       * Process all expired timers.
131157188Sache       */
13221308Sache      while (exp) {
13321308Sache#ifdef notdef
13421308Sache	StopTimer(exp);
13521308Sache#endif
13621308Sache	if (exp->func)
13721308Sache	  (*exp->func)(exp->arg);
13821308Sache	exp = exp->enext;
139157188Sache      }
140157188Sache    }
14121308Sache  }
14221308Sache}
14321308Sache
14421308Sachevoid
14521308SacheShowTimers()
14621308Sache{
14721308Sache  struct pppTimer *pt;
14821308Sache
14921308Sache  for (pt = TimerList; pt; pt = pt->next)
15021308Sache    fprintf(stderr, "%x: load = %d, rest = %d\r\n", pt, pt->load, pt->rest);
15121308Sache}
15221308Sache