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