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