"I am a person who works hard and plays hard."

Yuan Wei
Second Year Graduate Student Department of Computer Science
University of Virginia Charlottesville, VA 22903
Email: yw3f@cs.virginia.edu


Source Code Analysis

Main Page   Compound List   File List   Compound Members   File Members  

eventq.c

Go to the documentation of this file.
00001 /*
00002  * eventq.c - event queue manager routines
00003  *
00004  * This file is a part of the SimpleScalar tool suite written by
00005  * Todd M. Austin as a part of the Multiscalar Research Project.
00006  *  
00007  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00008  * 
00009  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00010  *
00011  * This source file is distributed "as is" in the hope that it will be
00012  * useful.  The tool set comes with no warranty, and no author or
00013  * distributor accepts any responsibility for the consequences of its
00014  * use. 
00015  * 
00016  * Everyone is granted permission to copy, modify and redistribute
00017  * this tool set under the following conditions:
00018  * 
00019  *    This source code is distributed for non-commercial use only. 
00020  *    Please contact the maintainer for restrictions applying to 
00021  *    commercial use.
00022  *
00023  *    Permission is granted to anyone to make or distribute copies
00024  *    of this source code, either as received or modified, in any
00025  *    medium, provided that all copyright notices, permission and
00026  *    nonwarranty notices are preserved, and that the distributor
00027  *    grants the recipient permission for further redistribution as
00028  *    permitted by this document.
00029  *
00030  *    Permission is granted to distribute this file in compiled
00031  *    or executable form under the same conditions that apply for
00032  *    source code, provided that either:
00033  *
00034  *    A. it is accompanied by the corresponding machine-readable
00035  *       source code,
00036  *    B. it is accompanied by a written offer, with no time limit,
00037  *       to give anyone a machine-readable copy of the corresponding
00038  *       source code in return for reimbursement of the cost of
00039  *       distribution.  This written offer must permit verbatim
00040  *       duplication by anyone, or
00041  *    C. it is distributed by someone who received only the
00042  *       executable form, and is accompanied by a copy of the
00043  *       written offer of source code that they received concurrently.
00044  *
00045  * In other words, you are welcome to use, share and improve this
00046  * source file.  You are forbidden to forbid anyone else to use, share
00047  * and improve what you give them.
00048  *
00049  * INTERNET: dburger@cs.wisc.edu
00050  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00051  *
00052  * $Id: eventq.c,v 1.1.1.1 2000/05/26 15:18:57 taustin Exp $
00053  *
00054  * $Log: eventq.c,v $
00055  * Revision 1.1.1.1  2000/05/26 15:18:57  taustin
00056  * SimpleScalar Tool Set
00057  *
00058  *
00059  * Revision 1.4  1998/08/27 08:28:03  taustin
00060  * implemented host interface description in host.h
00061  * added target interface support
00062  *
00063  * Revision 1.3  1997/03/11  01:12:18  taustin
00064  * updated copyright
00065  *
00066  * Revision 1.1  1996/12/05  18:52:32  taustin
00067  * Initial revision
00068  *
00069  *
00070  */
00071 
00072 #include <stdio.h>
00073 #include <stdlib.h>
00074 
00075 #include "host.h"
00076 #include "misc.h"
00077 #include "machine.h"
00078 #include "eventq.h"
00079 
00080 int eventq_max_events;
00081 int eventq_event_count;
00082 struct eventq_desc *eventq_pending;
00083 struct eventq_desc *eventq_free;
00084 
00085 static EVENTQ_ID_TYPE next_ID = 1;
00086 
00087 void
00088 eventq_init(int max_events)
00089 {
00090   eventq_max_events = max_events;
00091   eventq_event_count = 0;
00092   eventq_pending = NULL;
00093   eventq_free = NULL;
00094 }
00095 
00096 #define __QUEUE_EVENT(WHEN, ID, ACTION)                                 \
00097   struct eventq_desc *prev, *ev, *new;                                  \
00098   /* get a free event descriptor */                                     \
00099   if (!eventq_free)                                                     \
00100     {                                                                   \
00101       if (eventq_max_events && eventq_event_count >= eventq_max_events) \
00102         panic("too many events");                                       \
00103       eventq_free = calloc(1, sizeof(struct eventq_desc));              \
00104     }                                                                   \
00105   new = eventq_free;                                                    \
00106   eventq_free = eventq_free->next;                                      \
00107   /* plug in event data */                                              \
00108   new->when = (WHEN); (ID) = new->id = next_ID++; ACTION;               \
00109   /* locate insertion point */                                          \
00110   for (prev=NULL,ev=eventq_pending;                                     \
00111        ev && ev->when < when;                                           \
00112        prev=ev, ev=ev->next);                                           \
00113   /* insert new record */                                               \
00114   if (prev)                                                             \
00115     {                                                                   \
00116       /* insert middle or end */                                        \
00117       new->next = prev->next;                                           \
00118       prev->next = new;                                                 \
00119     }                                                                   \
00120   else                                                                  \
00121     {                                                                   \
00122       /* insert beginning */                                            \
00123       new->next = eventq_pending;                                       \
00124       eventq_pending = new;                                             \
00125     }
00126 
00127 EVENTQ_ID_TYPE
00128 eventq_queue_setbit(SS_TIME_TYPE when,
00129                     BITMAP_ENT_TYPE *bmap, int sz, int bitnum)
00130 {
00131   EVENTQ_ID_TYPE id;
00132   __QUEUE_EVENT(when, id,                                               \
00133                 new->action = EventSetBit; new->data.bit.bmap = bmap;   \
00134                 new->data.bit.sz = sz; new->data.bit.bitnum = bitnum);
00135   return id;
00136 }
00137 
00138 EVENTQ_ID_TYPE
00139 eventq_queue_clearbit(SS_TIME_TYPE when,
00140                       BITMAP_ENT_TYPE *bmap, int sz, int bitnum)
00141 {
00142   EVENTQ_ID_TYPE id;
00143   __QUEUE_EVENT(when, id,                                               \
00144                 new->action = EventClearBit; new->data.bit.bmap = bmap; \
00145                 new->data.bit.sz = sz; new->data.bit.bitnum = bitnum);
00146   return id;
00147 }
00148 
00149 EVENTQ_ID_TYPE
00150 eventq_queue_setflag(SS_TIME_TYPE when, int *pflag, int value)
00151 {
00152   EVENTQ_ID_TYPE id;
00153   __QUEUE_EVENT(when, id,                                               \
00154                 new->action = EventSetFlag;                             \
00155                 new->data.flag.pflag = pflag; new->data.flag.value = value);
00156   return id;
00157 }
00158 
00159 EVENTQ_ID_TYPE
00160 eventq_queue_addop(SS_TIME_TYPE when, int *summand, int addend)
00161 {
00162   EVENTQ_ID_TYPE id;
00163   __QUEUE_EVENT(when, id,                                               \
00164                 new->action = EventAddOp;                               \
00165                 new->data.addop.summand = summand;                      \
00166                 new->data.addop.addend = addend);
00167   return id;
00168 }
00169 
00170 EVENTQ_ID_TYPE
00171 eventq_queue_callback(SS_TIME_TYPE when,
00172                       void (*fn)(SS_TIME_TYPE time, int arg), int arg)
00173 {
00174   EVENTQ_ID_TYPE id;
00175   __QUEUE_EVENT(when, id,                                               \
00176                 new->action = EventCallback; new->data.callback.fn = fn;\
00177                 new->data.callback.arg = arg);
00178   return id;
00179 }
00180 
00181 #define EXECUTE_ACTION(ev, now)                                         \
00182   /* execute action */                                                  \
00183   switch (ev->action) {                                                 \
00184   case EventSetBit:                                                     \
00185     BITMAP_SET(ev->data.bit.bmap, ev->data.bit.sz, ev->data.bit.bitnum);\
00186     break;                                                              \
00187   case EventClearBit:                                                   \
00188     BITMAP_CLEAR(ev->data.bit.bmap, ev->data.bit.sz, ev->data.bit.bitnum);\
00189     break;                                                              \
00190   case EventSetFlag:                                                    \
00191     *ev->data.flag.pflag = ev->data.flag.value;                         \
00192     break;                                                              \
00193   case EventAddOp:                                                      \
00194     *ev->data.addop.summand += ev->data.addop.addend;                   \
00195     break;                                                              \
00196   case EventCallback:                                                   \
00197     (*ev->data.callback.fn)(now, ev->data.callback.arg);                \
00198     break;                                                              \
00199   default:                                                              \
00200     panic("bogus event action");                                        \
00201   }
00202 
00203 /* execute an event immediately, returns non-zero if the event was
00204    located an deleted */
00205 int
00206 eventq_execute(EVENTQ_ID_TYPE id)
00207 {
00208   struct eventq_desc *prev, *ev;
00209 
00210   for (prev=NULL,ev=eventq_pending; ev; prev=ev,ev=ev->next)
00211     {
00212       if (ev->id == id)
00213         {
00214           if (prev)
00215             {
00216               /* middle of end of list */
00217               prev->next = ev->next;
00218             }
00219           else /* !prev */
00220             {
00221               /* beginning of list */
00222               eventq_pending = ev->next;
00223             }
00224 
00225           /* handle action, now is munged */
00226           EXECUTE_ACTION(ev, 0);
00227 
00228           /* put event on free list */
00229           ev->next = eventq_free;
00230           eventq_free = ev;
00231 
00232           /* return success */
00233           return TRUE;
00234         }
00235     }
00236   /* not found */
00237   return FALSE;
00238 }
00239 
00240 /* remove an event from the eventq, action is never performed, returns
00241    non-zero if the event was located an deleted */
00242 int
00243 eventq_remove(EVENTQ_ID_TYPE id)
00244 {
00245   struct eventq_desc *prev, *ev;
00246 
00247   for (prev=NULL,ev=eventq_pending; ev; prev=ev,ev=ev->next)
00248     {
00249       if (ev->id == id)
00250         {
00251           if (prev)
00252             {
00253               /* middle of end of list */
00254               prev->next = ev->next;
00255             }
00256           else /* !prev */
00257             {
00258               /* beginning of list */
00259               eventq_pending = ev->next;
00260             }
00261 
00262           /* put event on free list */
00263           ev->next = eventq_free;
00264           eventq_free = ev;
00265 
00266           /* return success */
00267           return TRUE;
00268         }
00269     }
00270   /* not found */
00271   return FALSE;
00272 }
00273 
00274 void
00275 eventq_service_events(SS_TIME_TYPE now)
00276 {
00277   while (eventq_pending && eventq_pending->when <= now)
00278     {
00279       struct eventq_desc *ev = eventq_pending;
00280 
00281       /* handle action */
00282       EXECUTE_ACTION(ev, now);
00283 
00284       /* return the event record to the free list */
00285       eventq_pending = ev->next;
00286       ev->next = eventq_free;
00287       eventq_free = ev;
00288   }
00289 }
00290 
00291 void
00292 eventq_dump(FILE *stream)
00293 {
00294   struct eventq_desc *ev;
00295 
00296   if (!stream)
00297     stream = stderr;
00298 
00299   fprintf(stream, "Pending Events: ");
00300   for (ev=eventq_pending; ev; ev=ev->next)
00301     {
00302       fprintf(stream, "@ %.0f:%s:",
00303               (double)ev->when,
00304               ev->action == EventSetBit ? "set bit"
00305               : ev->action == EventClearBit ? "clear bit"
00306               : ev->action == EventSetFlag ? "set flag"
00307               : ev->action == EventAddOp ? "add operation"
00308               : ev->action == EventCallback ? "call back"
00309               : (abort(), ""));
00310       switch (ev->action) {
00311       case EventSetBit:
00312       case EventClearBit:
00313         fprintf(stream, "0x%p, %d, %d",
00314                 ev->data.bit.bmap, ev->data.bit.sz, ev->data.bit.bitnum);
00315         break;
00316       case EventSetFlag:
00317         fprintf(stream, "0x%p, %d", ev->data.flag.pflag, ev->data.flag.value);
00318         break;
00319       case EventAddOp:
00320         fprintf(stream, "0x%p, %d",
00321                 ev->data.addop.summand, ev->data.addop.addend);
00322         break;
00323       case EventCallback:
00324         fprintf(stream, "0x%p, %d",
00325                 ev->data.callback.fn, ev->data.callback.arg);
00326         break;
00327       default:
00328         panic("bogus event action");
00329       }
00330       fprintf(stream, " ");
00331     }
00332 }


UVa CS Department of Computer Science
School of Engineering, University of Virginia
151 Engineer's Way, P.O. Box 400740
Charlottesville, Virginia 22904-4740

(434) 982-2200  Fax: (434) 982-2214