File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pimdd / callout.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jun 12 07:58:55 2017 UTC (6 years, 11 months ago) by misho
Branches: pimdd, MAIN
CVS tags: v0_2_1p0, v0_2_1, HEAD
pimdd-dense 0.2.1.0_2

    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>