Annotation of embedaddon/pimdd/callout.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * The mrouted program is covered by the license in the accompanying file
        !             3:  * named "LICENSE.mrouted". Use of the mrouted program represents acceptance
        !             4:  * of the terms and conditions listed in that file.
        !             5:  *
        !             6:  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
        !             7:  * Leland Stanford Junior University.
        !             8:  *
        !             9:  *
        !            10:  * callout.c,v 3.8.4.5 1997/05/16 20:18:25 fenner Exp
        !            11:  */
        !            12: 
        !            13: #include "defs.h"
        !            14: 
        !            15: /* the code below implements a callout queue */
        !            16: static int id = 0;
        !            17: static struct timeout_q  *Q = 0; /* pointer to the beginning of timeout queue */
        !            18: 
        !            19: struct timeout_q {
        !            20:     struct timeout_q *next;            /* next event */
        !            21:     int                     id;  
        !            22:     cfunc_t          func;             /* function to call */
        !            23:     void            *data;             /* func's data */
        !            24:     int              time;             /* time offset to next event*/
        !            25: };
        !            26: 
        !            27: #ifdef CALLOUT_DEBUG
        !            28: static void print_Q __P((void));
        !            29: #else
        !            30: #define        print_Q()       
        !            31: #endif
        !            32: 
        !            33: void
        !            34: callout_init()
        !            35: {
        !            36:     Q = (struct timeout_q *) 0;
        !            37: }
        !            38: 
        !            39: void
        !            40: free_all_callouts()
        !            41: {
        !            42:     struct timeout_q *p;
        !            43:     
        !            44:     while (Q) {
        !            45:        p = Q;
        !            46:        Q = Q->next;
        !            47:        free(p);
        !            48:     }
        !            49: }
        !            50: 
        !            51: 
        !            52: /*
        !            53:  * elapsed_time seconds have passed; perform all the events that should
        !            54:  * happen.
        !            55:  */
        !            56: void
        !            57: age_callout_queue(elapsed_time)
        !            58:     int elapsed_time;
        !            59: {
        !            60:     struct timeout_q *ptr, *expQ;
        !            61:     
        !            62: #ifdef CALLOUT_DEBUG
        !            63:     IF_DEBUG(DEBUG_TIMEOUT)
        !            64:        log(LOG_DEBUG, 0, "aging queue (elapsed time %d):", elapsed_time);
        !            65:     print_Q();
        !            66: #endif
        !            67: 
        !            68:     expQ = Q;
        !            69:     ptr = NULL;
        !            70:     
        !            71:     while (Q) {
        !            72:        if (Q->time > elapsed_time) {
        !            73:            Q->time -= elapsed_time;
        !            74:            if (ptr) {
        !            75:                ptr->next = NULL;
        !            76:                break;
        !            77:            }
        !            78:            return;
        !            79:        } else {
        !            80:            elapsed_time -= Q->time;
        !            81:            ptr = Q;
        !            82:            Q = Q->next;
        !            83:        }
        !            84:     }
        !            85:     
        !            86:     /* handle queue of expired timers */
        !            87:     while (expQ) {
        !            88:        ptr = expQ;
        !            89:        if (ptr->func)
        !            90:            ptr->func(ptr->data);
        !            91:        expQ = expQ->next;
        !            92:        free(ptr);
        !            93:     }
        !            94: }
        !            95: 
        !            96: /*
        !            97:  * Return in how many seconds age_callout_queue() would like to be called.
        !            98:  * Return -1 if there are no events pending.
        !            99:  */
        !           100: int
        !           101: timer_nextTimer()
        !           102: {
        !           103:     if (Q) {
        !           104:        if (Q->time < 0) {
        !           105:            log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d", 
        !           106:                Q->time);
        !           107:            return 0;
        !           108:        }
        !           109:        return Q->time;
        !           110:     }
        !           111:     return -1;
        !           112: }
        !           113: 
        !           114: /* 
        !           115:  * sets the timer
        !           116:  */
        !           117: int
        !           118: timer_setTimer(delay, action, data)
        !           119:     int        delay;          /* number of units for timeout */
        !           120:     cfunc_t    action;         /* function to be called on timeout */
        !           121:     void       *data;          /* what to call the timeout function with */
        !           122: {
        !           123:     struct     timeout_q  *ptr, *node, *prev;
        !           124:     
        !           125: #ifdef CALLOUT_DEBUG
        !           126:     IF_DEBUG(DEBUG_TIMEOUT)
        !           127:        log(LOG_DEBUG, 0, "setting timer:");
        !           128:     print_Q();
        !           129: #endif
        !           130: 
        !           131:     /* create a node */        
        !           132:     node = (struct timeout_q *)malloc(sizeof(struct timeout_q));
        !           133:     if (node == 0) {
        !           134:        log(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n");
        !           135:        return -1;
        !           136:     }
        !           137:     node->func = action; 
        !           138:     node->data = data;
        !           139:     node->time = delay; 
        !           140:     node->next = 0;    
        !           141:     node->id   = ++id;
        !           142:     
        !           143:     prev = ptr = Q;
        !           144:     
        !           145:     /* insert node in the queue */
        !           146:     
        !           147:     /* if the queue is empty, insert the node and return */
        !           148:     if (!Q)
        !           149:        Q = node;
        !           150:     else {
        !           151:        /* chase the pointer looking for the right place */
        !           152:        while (ptr) {
        !           153:            
        !           154:            if (delay < ptr->time) {
        !           155:                /* right place */
        !           156:                
        !           157:                node->next = ptr;
        !           158:                if (ptr == Q)
        !           159:                    Q = node;
        !           160:                else
        !           161:                    prev->next = node;
        !           162:                ptr->time -= node->time;
        !           163:                return node->id;
        !           164:            } else  {
        !           165:                /* keep moving */
        !           166:                
        !           167:                delay -= ptr->time; node->time = delay;
        !           168:                prev = ptr;
        !           169:                ptr = ptr->next;
        !           170:            }
        !           171:        }
        !           172:        prev->next = node;
        !           173:     }
        !           174:     return node->id;
        !           175: }
        !           176: 
        !           177: /* returns the time until the timer is scheduled */
        !           178: int
        !           179: timer_leftTimer(timer_id)
        !           180:     int timer_id;
        !           181: {
        !           182:     struct timeout_q *ptr;
        !           183:     int left = 0;
        !           184:        
        !           185:     if (!timer_id)
        !           186:        return -1;
        !           187:     
        !           188:     for (ptr = Q; ptr; ptr = ptr->next) {
        !           189:        left += ptr->time;
        !           190:        if (ptr->id == timer_id)
        !           191:            return left;
        !           192:     }
        !           193:     return -1;
        !           194: }
        !           195: 
        !           196: /* clears the associated timer */
        !           197: void
        !           198: timer_clearTimer(timer_id)
        !           199:     int  timer_id;
        !           200: {
        !           201:     struct timeout_q  *ptr, *prev;
        !           202:     
        !           203:     if (!timer_id)
        !           204:        return;
        !           205:     
        !           206:     prev = ptr = Q;
        !           207:     
        !           208:     /*
        !           209:      * find the right node, delete it. the subsequent node's time
        !           210:      * gets bumped up
        !           211:      */
        !           212:     
        !           213:     while (ptr) {
        !           214:        if (ptr->id == timer_id) {
        !           215:            /* got the right node */
        !           216:            
        !           217:            /* unlink it from the queue */
        !           218:            if (ptr == Q)
        !           219:                Q = Q->next;
        !           220:            else
        !           221:                prev->next = ptr->next;
        !           222:            
        !           223:            /* increment next node if any */
        !           224:            if (ptr->next != 0)
        !           225:                (ptr->next)->time += ptr->time;
        !           226:            
        !           227:            if (ptr->data)
        !           228:                free(ptr->data);
        !           229:            free(ptr);
        !           230:            return;
        !           231:        }
        !           232:        prev = ptr;
        !           233:        ptr = ptr->next;
        !           234:     }
        !           235: }
        !           236: 
        !           237: #ifdef CALLOUT_DEBUG
        !           238: /*
        !           239:  * debugging utility
        !           240:  */
        !           241: static void
        !           242: print_Q()
        !           243: {
        !           244:     struct timeout_q  *ptr;
        !           245:     
        !           246:     IF_DEBUG(DEBUG_TIMEOUT)
        !           247:        for (ptr = Q; ptr; ptr = ptr->next)
        !           248:            log(LOG_DEBUG, 0, "(%d,%d) ", ptr->id, ptr->time);
        !           249: }
        !           250: #endif /* CALLOUT_DEBUG */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>