Annotation of embedaddon/pimd/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: #if 0
        !            28: #define CALLOUT_DEBUG 1
        !            29: #define CALLOUT_DEBUG2 1
        !            30: #endif /* 0 */
        !            31: #ifdef CALLOUT_DEBUG2
        !            32: static void print_Q((void);
        !            33: #else
        !            34: #define        print_Q()       
        !            35: #endif
        !            36: 
        !            37: void
        !            38: callout_init()
        !            39: {
        !            40:     Q = (struct timeout_q *) 0;
        !            41: }
        !            42: 
        !            43: void
        !            44: free_all_callouts()
        !            45: {
        !            46:     struct timeout_q *p;
        !            47:     
        !            48:     while (Q) {
        !            49:        p = Q;
        !            50:        Q = Q->next;
        !            51:        free(p);
        !            52:     }
        !            53: }
        !            54: 
        !            55: 
        !            56: /*
        !            57:  * elapsed_time seconds have passed; perform all the events that should
        !            58:  * happen.
        !            59:  */
        !            60: void
        !            61: age_callout_queue(elapsed_time)
        !            62:     int elapsed_time;
        !            63: {
        !            64:     struct timeout_q *ptr, *expQ;
        !            65:     
        !            66: #ifdef CALLOUT_DEBUG
        !            67:     IF_DEBUG(DEBUG_TIMEOUT)
        !            68:        logit(LOG_DEBUG, 0, "aging queue (elapsed time %d):", elapsed_time);
        !            69:     print_Q();
        !            70: #endif
        !            71:     
        !            72:     expQ = Q;
        !            73:     ptr = NULL;
        !            74:     
        !            75:     while (Q) {
        !            76:        if (Q->time > elapsed_time) {
        !            77:            Q->time -= elapsed_time;
        !            78:            if (ptr) {
        !            79:                ptr->next = NULL;
        !            80:                break;
        !            81:            }
        !            82:            return;
        !            83:        } else {
        !            84:            elapsed_time -= Q->time;
        !            85:            ptr = Q;
        !            86:            Q = Q->next;
        !            87:        }
        !            88:     }
        !            89:     
        !            90:     /* handle queue of expired timers */
        !            91:     while (expQ) {
        !            92:        ptr = expQ;
        !            93:        if (ptr->func)
        !            94:            ptr->func(ptr->data);
        !            95:        expQ = expQ->next;
        !            96:        free(ptr);
        !            97:     }
        !            98: }
        !            99: 
        !           100: /*
        !           101:  * Return in how many seconds age_callout_queue() would like to be called.
        !           102:  * Return -1 if there are no events pending.
        !           103:  */
        !           104: int
        !           105: timer_nextTimer()
        !           106: {
        !           107:     if (Q) {
        !           108:        if (Q->time < 0) {
        !           109:            logit(LOG_WARNING, 0, "timer_nextTimer top of queue says %d", 
        !           110:                Q->time);
        !           111:            return 0;
        !           112:        }
        !           113:        return Q->time;
        !           114:     }
        !           115:     return -1;
        !           116: }
        !           117: 
        !           118: /* 
        !           119:  * sets the timer
        !           120:  */
        !           121: int
        !           122: timer_setTimer(delay, action, data)
        !           123:     int        delay;          /* number of units for timeout */
        !           124:     cfunc_t    action;         /* function to be called on timeout */
        !           125:     void       *data;          /* what to call the timeout function with */
        !           126: {
        !           127:     struct     timeout_q  *ptr, *node, *prev;
        !           128:     
        !           129: #ifdef CALLOUT_DEBUG
        !           130:     IF_DEBUG(DEBUG_TIMEOUT)
        !           131:        logit(LOG_DEBUG, 0, "setting timer:");
        !           132:     print_Q();
        !           133: #endif
        !           134:     
        !           135:     /* create a node */        
        !           136:     node = (struct timeout_q *)calloc(1, sizeof(struct timeout_q));
        !           137:     if (!node) {
        !           138:        logit(LOG_ERR, 0, "Failed calloc() in timer_settimer\n");
        !           139:        return -1;
        !           140:     }
        !           141:     node->func = action; 
        !           142:     node->data = data;
        !           143:     node->time = delay; 
        !           144:     node->next = 0;    
        !           145:     node->id   = ++id;
        !           146:     
        !           147:     prev = ptr = Q;
        !           148:     
        !           149:     /* insert node in the queue */
        !           150:     
        !           151:     /* if the queue is empty, insert the node and return */
        !           152:     if (!Q)
        !           153:        Q = node;
        !           154:     else {
        !           155:        /* chase the pointer looking for the right place */
        !           156:        while (ptr) {
        !           157:            
        !           158:            if (delay < ptr->time) {
        !           159:                /* right place */
        !           160:                
        !           161:                node->next = ptr;
        !           162:                if (ptr == Q)
        !           163:                    Q = node;
        !           164:                else
        !           165:                    prev->next = node;
        !           166:                ptr->time -= node->time;
        !           167:                print_Q();
        !           168:                return node->id;
        !           169:            } else  {
        !           170:                /* keep moving */
        !           171:                
        !           172:                delay -= ptr->time; node->time = delay;
        !           173:                prev = ptr;
        !           174:                ptr = ptr->next;
        !           175:            }
        !           176:        }
        !           177:        prev->next = node;
        !           178:     }
        !           179:     print_Q();
        !           180:     return node->id;
        !           181: }
        !           182: 
        !           183: /* returns the time until the timer is scheduled */
        !           184: int
        !           185: timer_leftTimer(timer_id)
        !           186:     int timer_id;
        !           187: {
        !           188:     struct timeout_q *ptr;
        !           189:     int left = 0;
        !           190:        
        !           191:     if (!timer_id)
        !           192:        return -1;
        !           193:     
        !           194:     for (ptr = Q; ptr; ptr = ptr->next) {
        !           195:        left += ptr->time;
        !           196:        if (ptr->id == timer_id)
        !           197:            return left;
        !           198:     }
        !           199:     return -1;
        !           200: }
        !           201: 
        !           202: /* clears the associated timer */
        !           203: void
        !           204: timer_clearTimer(timer_id)
        !           205:     int  timer_id;
        !           206: {
        !           207:     struct timeout_q  *ptr, *prev;
        !           208:     
        !           209:     if (!timer_id)
        !           210:        return;
        !           211:     
        !           212:     prev = ptr = Q;
        !           213:     
        !           214:     /*
        !           215:      * find the right node, delete it. the subsequent node's time
        !           216:      * gets bumped up
        !           217:      */
        !           218:     
        !           219:     print_Q();
        !           220:     while (ptr) {
        !           221:        if (ptr->id == timer_id) {
        !           222:            /* got the right node */
        !           223:            
        !           224:            /* unlink it from the queue */
        !           225:            if (ptr == Q)
        !           226:                Q = Q->next;
        !           227:            else
        !           228:                prev->next = ptr->next;
        !           229:            
        !           230:            /* increment next node if any */
        !           231:            if (ptr->next != 0)
        !           232:                (ptr->next)->time += ptr->time;
        !           233:            
        !           234:            if (ptr->data)
        !           235:                free(ptr->data);
        !           236:            free(ptr);
        !           237:            print_Q();
        !           238:            return;
        !           239:        }
        !           240:        prev = ptr;
        !           241:        ptr = ptr->next;
        !           242:     }
        !           243:     print_Q();
        !           244: }
        !           245: 
        !           246: #ifdef CALLOUT_DEBUG2
        !           247: /*
        !           248:  * debugging utility
        !           249:  */
        !           250: static void
        !           251: print_Q()
        !           252: {
        !           253:     struct timeout_q  *ptr;
        !           254:     
        !           255:     IF_DEBUG(DEBUG_TIMEOUT)
        !           256:        for (ptr = Q; ptr; ptr = ptr->next)
        !           257:            logit(LOG_DEBUG, 0, "(%d,%d) ", ptr->id, ptr->time);
        !           258: }
        !           259: #endif /* CALLOUT_DEBUG2 */
        !           260: 
        !           261: /**
        !           262:  * Local Variables:
        !           263:  *  version-control: t
        !           264:  *  indent-tabs-mode: t
        !           265:  *  c-file-style: "ellemtel"
        !           266:  *  c-basic-offset: 4
        !           267:  * End:
        !           268:  */

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