VIS

src/truesim/truesimMain.c

Go to the documentation of this file.
00001 
00020 #include "truesimInt.h"
00021 
00022 /*---------------------------------------------------------------------------*/
00023 /* Constant declarations                                                     */
00024 /*---------------------------------------------------------------------------*/
00025 
00026 
00027 /*---------------------------------------------------------------------------*/
00028 /* Type declarations                                                         */
00029 /*---------------------------------------------------------------------------*/
00030 
00031 
00032 /*---------------------------------------------------------------------------*/
00033 /* Structure declarations                                                    */
00034 /*---------------------------------------------------------------------------*/
00035 
00036 
00037 /*---------------------------------------------------------------------------*/
00038 /* Variable declarations                                                     */
00039 /*---------------------------------------------------------------------------*/
00040 
00041 static long numEvents;
00042 
00043 extern int truesimVerbose;
00044 extern int truesimRptHeader;
00045 
00046 /*---------------------------------------------------------------------------*/
00047 /* Macro declarations                                                        */
00048 /*---------------------------------------------------------------------------*/
00049 
00052 /*---------------------------------------------------------------------------*/
00053 /* Static function prototypes                                                */
00054 /*---------------------------------------------------------------------------*/
00055 
00056 static void InsertInputEvents(st_table *nodeToSimTable, EventQueue *queue, array_t *inputArray, char *vector);
00057 static void SinglePatternSimulate(Ntk_Network_t *network, EventQueue *queue);
00058 static void HouseKeeping(EventQueue *queue, Event *threshevent);
00059 static void InsertFanouts(Ntk_Node_t *node, st_table *fanoutTable);
00060 static void PerformSecondPass(Ntk_Network_t *network, EventQueue *queue, st_table *fanoutTable);
00061 static void ScheduleEvent(EventQueue *queue, Ntk_Node_t *node, TrueSim_t *sim, char value);
00062 static void RescheduleEvent(EventQueue *queue, Ntk_Node_t *node, TrueSim_t *sim, char value);
00063 static void CancelEvent(EventQueue *queue, TrueSim_t *sim);
00064 static void InsertInBin(Event **wheel, Event *event);
00065 static EventQueue * InitQueue(void);
00066 static void NewPage(EventQueue *queue);
00067 static enum st_retval stTrueSimFree(char *key, char *value, char *arg);
00068 
00072 /*---------------------------------------------------------------------------*/
00073 /* Definition of exported functions                                          */
00074 /*---------------------------------------------------------------------------*/
00075 
00095 int
00096 Truesim_RealDelayPatternSimulate(
00097   Ntk_Network_t *network,
00098   array_t *inputArray,
00099   array_t *patternArray)
00100 {
00101   Ntk_Node_t *node;
00102   int numVectors = array_n(patternArray);
00103   int i;
00104   EventQueue *queue;
00105   st_table *nodeToSimTable = TruesimNetworkReadSimTable(network);
00106   lsGen gen;
00107 
00108   if (nodeToSimTable == NIL(st_table)) {
00109     (void) fprintf(vis_stderr,
00110                    "** truesim error: Simulation structures not initialized\n");
00111     (void) fprintf(vis_stderr,
00112                    "** truesim error: Call Truesim_InitializeSimulation before ");
00113     (void) fprintf(vis_stderr,"calling this function.\n");
00114     return -1;
00115   }
00116 
00117   /* Initialize the converging list data structure */
00118   queue = InitQueue();
00119 
00120   /* Initialize node simulation data structures */
00121   TruesimInitializeActivityFields(network,nodeToSimTable);
00122 
00123   /* Warmup simulation. Simulate the first vector to initialize internal nodes
00124      in the network. */
00125   TruesimWarmUpPatternSimulate(network,inputArray,
00126                                array_fetch(char *,patternArray,0));
00127   
00128   /* Performs simulation of all the vectors */
00129   for (i = 1; i < numVectors; i++) {
00130     char *stimulus;
00131     stimulus = array_fetch(char *,patternArray,i);
00132     InsertInputEvents(nodeToSimTable,queue,inputArray,stimulus);
00133     SinglePatternSimulate(network,queue);
00134 
00135     if (truesimVerbose) {
00136       if (truesimRptHeader != -1) {
00137         if (i % truesimRptHeader == 0) 
00138           TruesimPrintNameHeader(network);
00139       }
00140       TruesimPrintNetworkNodeLogicState(network);
00141     }
00142   }
00143 
00144   /* Free the queue */
00145   if (queue != NIL(EventQueue)) {
00146     while (queue->freeList != NIL(Event *)) {
00147       Event **next;
00148       next = (Event **) queue->freeList[0];
00149       FREE(queue->freeList);
00150       queue->freeList = next;
00151     }
00152     FREE(queue->wheel);
00153     FREE(queue);
00154   }
00155   
00156   /* Update the statistics for each node */
00157   Ntk_NetworkForEachNode(network,gen,node) {
00158     TrueSim_t *sim;
00159     if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00160       (void) fprintf(vis_stderr,
00161                      "** truesim fatal:In Truesim_RealDelayPatternSimulate\n");
00162       (void) fprintf(vis_stderr,"        Sim. structure missing for %s\n",
00163                      Ntk_NodeReadName(node));
00164       
00165       assert(0);
00166     }
00167     /* Get the switching probability and the signal probability */
00168     sim->switching /= ((float) array_n(patternArray));
00169     sim->prob /= ((float) array_n(patternArray));
00170   }
00171 
00172   return 1;
00173 
00174 } /* End of Truesim_RealDelayPatternSimulate */
00175 
00176 
00197 void
00198 Truesim_InitializeSimulation(
00199   Ntk_Network_t *network,
00200   char *delayFile,
00201   boolean truedelay,
00202   int header,
00203   int verbose,
00204   st_table *nodeDelayTable)
00205 {
00206   Truesim_Info_t *simInfo;
00207   st_table *nodeToSimTable;
00208   lsGen gen;
00209   Ntk_Node_t *node;
00210   TrueSim_t *sim;
00211   float delay,load;
00212   float *delayPtr;
00213 
00214   delay = -1.0; /* To keep the compiler happy */
00215   /* Allocate the Truesim_Info_t * structure */
00216   simInfo = ALLOC(Truesim_Info_t,1);
00217   Ntk_NetworkAddApplInfo(network,TRUESIM_NETWORK_APPL_KEY,
00218                          (Ntk_ApplInfoFreeFn)TruesimEndSimulation,
00219                          (void *)simInfo);
00220   simInfo->depthArray = NIL(array_t);
00221   simInfo->nodeToSimTable = NIL(st_table);
00222 
00223   /* Allocate simulation structure for each node in the network and
00224      put it in a table.*/
00225   nodeToSimTable = st_init_table(st_ptrcmp,st_ptrhash);
00226 
00227   if (delayFile) {
00228     TruesimReadDelayFile(network,delayFile,nodeToSimTable);
00229   } else { /* Read from nodeDelayTable */
00230     Ntk_NetworkForEachNode(network,gen,node) {
00231       sim = ALLOC(TrueSim_t,1);
00232       /* I assume inputs to have zero delay. */
00233       if (Ntk_NodeTestIsPrimaryInput(node)) {
00234         delay = 0;
00235       }
00236       if (nodeDelayTable == NIL(st_table) ||
00237           !st_lookup(nodeDelayTable,(char *)node,&delayPtr)) {
00238         if (Ntk_NodeTestIsPrimaryInput(node)) {
00239           load = (float) Ntk_NodeReadNumFanouts(node);
00240         } else if (Ntk_NodeTestIsPrimaryOutput(node)){
00241           /* Sometimes primary outputs can fanout to other internal nodes */
00242           load = (float) Ntk_NodeReadNumFanouts(node);
00243           load = load ? load : 1.0;
00244           delay = load;
00245         } else {
00246           delay = load = (float) Ntk_NodeReadNumFanouts(node);
00247         }
00248       } else { /* if you do find it */
00249         delay = load = *delayPtr;
00250       }
00251       sim->delay = delay;
00252       sim->load = load;
00253       st_insert(nodeToSimTable, (char *)node, (char *)sim);
00254     }
00255   }
00256   
00257   /* Set the global variables truesimRptHeader, truesimVerbose */
00258   simInfo->trueDelay = truedelay;
00259   simInfo->repeatHeader = truesimRptHeader = header;
00260   simInfo->truesimVerbose = truesimVerbose = verbose;
00261   simInfo->nodeToSimTable = nodeToSimTable;
00262   
00263   /* Fill in depth field for each node */
00264   Truesim_NetworkUpdateNodeTopologicalDepth(network);
00265 
00266   return;
00267 } /* End of Truesim_InitializeSimulation */
00268 
00269 
00279 void
00280 Truesim_QuitSimulation(Ntk_Network_t *network)
00281 {
00282   Ntk_NetworkFreeApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00283   
00284 } /* End of Truesim_QuitSimulation */
00285 
00286 
00287 /*---------------------------------------------------------------------------*/
00288 /* Definition of internal functions                                          */
00289 /*---------------------------------------------------------------------------*/
00299 void
00300 TruesimEndSimulation(void *data)
00301 {
00302   st_table *nodeToSimTable;
00303   array_t *depthArray,*tempArray;
00304   Truesim_Info_t *dataBody;
00305   int i;
00306   
00307   nodeToSimTable = ((Truesim_Info_t *)data)->nodeToSimTable;
00308   depthArray = ((Truesim_Info_t *)data)->depthArray;
00309   
00310   if (nodeToSimTable) {
00311     st_foreach(nodeToSimTable,stTrueSimFree,NIL(char));
00312     st_free_table(nodeToSimTable);
00313   }
00314 
00315   arrayForEachItem(array_t *,depthArray,i,tempArray) {
00316     array_free(tempArray);
00317   }
00318   array_free(depthArray);
00319   
00320   dataBody = (Truesim_Info_t *)data;
00321   FREE(dataBody);
00322   
00323 } /* End of TruesimEndSimulation */
00324 
00325 
00326 /*---------------------------------------------------------------------------*/
00327 /* Definition of static functions                                            */
00328 /*---------------------------------------------------------------------------*/
00338 static void
00339 InsertInputEvents(
00340   st_table *nodeToSimTable,
00341   EventQueue *queue,              
00342   array_t *inputArray,
00343   char *vector)
00344 {
00345   Ntk_Node_t *node;
00346   TrueSim_t *sim;
00347   int i;
00348   char prev;
00349 
00350   arrayForEachItem(Ntk_Node_t *,inputArray,i,node) {
00351     if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00352       (void) fprintf(vis_stderr,"** truesim fatal: In InsertInputEvents\n");
00353       (void) fprintf(vis_stderr,"        Sim. structure missing for %s\n",
00354                      Ntk_NodeReadName(node));
00355       assert(0);
00356     }
00357     prev = sim->value;
00358     if (prev != vector[i]) {
00359       ScheduleEvent(queue,node,sim,vector[i]);
00360     }
00361   }
00362   
00363 } /* End of InsertInputEvents */
00364 
00365 
00377 static void
00378 SinglePatternSimulate(
00379   Ntk_Network_t *network,                     
00380   EventQueue *queue)
00381 {
00382   Event *currentEvent;
00383   Event **wheel;
00384   long currbin,halfPeriodBin;
00385   Ntk_Node_t *gate;  /* Node being simulated/evaluated */
00386   st_table *fanoutTable; /* Nodes in the fanout */
00387   st_table *nodeToSimTable = TruesimNetworkReadSimTable(network);
00388   TrueSim_t *simInfo;
00389   long eventType;
00390 
00391   /* No events to start with */
00392   if (numEvents == 0)
00393     return;
00394 
00395   wheel = queue->wheel;
00396   halfPeriodBin = WHEEL_POS(HALF_PERIOD - 1);
00397 
00398   currbin = 0;
00399 
00400   /* Find the first sim, th2, th3 event */ 
00401   /* Events th2 and th3 are control events. They help in housekeeping of the
00402      event queue. When a th2 event is reached, the time ranges for each slot in
00403      the wheel is increased. The threshold events are different from the
00404      simulation events in that they are not related to simulation. They help in
00405      the timely update of the wheel. */
00406   do {
00407     fanoutTable = st_init_table(st_ptrcmp,st_ptrhash);
00408 
00409     do { /* examine each bin */
00410       currentEvent = wheel[currbin];
00411       eventType = TYPE(currentEvent);   
00412 
00413       switch (eventType) {
00414       case SIM_EVENT_C :
00415         /* Simply cancel the event as this is a cancel event */
00416         wheel[currbin] = NEXT_VER(currentEvent); 
00417         /* free current event and obtain next */
00418         EVENT_FREE(queue, currentEvent);
00419         numEvents--;
00420         break;
00421       case SIM_EVENT_0 :        
00422         wheel[currbin] = NEXT_VER(currentEvent); 
00423         queue->time = TIME(currentEvent);
00424         gate = GATE(currentEvent); 
00425         if (!st_lookup(nodeToSimTable,(char *)gate,&simInfo)) {
00426           (void) fprintf(vis_stderr,"** truesim fatal: In case SIM_EVENT_0\n");
00427           (void) fprintf(vis_stderr,"        Sim. structure missing for %s\n",
00428                          Ntk_NodeReadName(gate));
00429 
00430           assert(0);
00431         }
00432         (simInfo->switching)++;
00433         simInfo->value = '0';
00434         /* Collect the fanouts that may need to be scheduled. This is used for
00435            the second pass */
00436         InsertFanouts(gate,fanoutTable);
00437         /* free current event and obtain next */
00438         EVENT_FREE(queue, currentEvent);
00439         simInfo->event = NIL(Event);
00440         numEvents--;
00441         break;
00442       case SIM_EVENT_1 :        
00443         wheel[currbin] = NEXT_VER(currentEvent); 
00444         queue->time = TIME(currentEvent);
00445         gate = GATE(currentEvent);
00446         if (!st_lookup(nodeToSimTable,(char *)gate,&simInfo)) {
00447           (void) fprintf(vis_stderr,"** truesim fatal: In case SIM_EVENT_1\n");
00448           (void) fprintf(vis_stderr,"        Sim. structure missing for %s\n",
00449                          Ntk_NodeReadName(gate));
00450           assert(0);
00451         }
00452         (simInfo->switching)++;
00453         simInfo->value = '1';
00454         (simInfo->prob)++;
00455         /* Collect the fanouts that may need to be scheduled. This is used for
00456            the second pass */
00457         InsertFanouts(gate,fanoutTable);                                
00458         /* free current event and obtain next */
00459         EVENT_FREE(queue, currentEvent);
00460         simInfo->event = NIL(Event);
00461         numEvents--;
00462         break;
00463       case THRESHOLD_1 :        
00464         currbin++; 
00465         currbin &= ((1 << LOG_WHEEL_SIZE) - 1);
00466         break;
00467       case THRESHOLD_2 :        
00468         HouseKeeping(queue, currentEvent);
00469         currbin = halfPeriodBin + 1;
00470         break;
00471       case THRESHOLD_3 :        
00472         HouseKeeping(queue, currentEvent);
00473         currbin = 0;
00474         break;
00475       default:
00476         (void) fprintf(vis_stderr,"** truesim fatal: Unknown event %ld\n",
00477                        eventType);
00478         assert(0);
00479       } 
00480     } while (NEXT_BOT(currentEvent) != currentEvent);
00481 
00482     if (truesimVerbose > 2) {
00483       (void) fprintf(vis_stdout,"Simulation time tick %ld",queue->time);
00484       TruesimPrintNetworkNodeLogicState(network);
00485     }
00486     
00487     /* We are finished processing a vertical list. A vertical list has events
00488        scheduled for the same time. Now perform the second pass of the
00489        simulation. */
00490     PerformSecondPass(network,queue,fanoutTable);
00491     st_free_table(fanoutTable);
00492   } while (numEvents > 0);
00493 
00494   /* End of simulation for one pattern */
00495   /* Reset the queue */
00496   queue->current = NIL(Event);
00497   queue->time = 0;
00498   TIME(queue->th1) = PERIOD - 1;
00499   TIME(queue->th2) = PERIOD - 1;
00500   TIME(queue->th3) = PERIOD - 1;
00501 
00502 } /* End of SinglePatternSimulate */
00503 
00504 
00517 static void
00518 HouseKeeping(
00519   EventQueue *queue,
00520   Event *threshevent)
00521 {
00522   Event **wheel;
00523   Event *event, *threshold1;
00524   Event *temp;
00525   long threshold1_time;
00526 
00527   wheel = queue->wheel;
00528 
00529   /* add T/2 to all threshold events */
00530   threshold1 = queue->th1;
00531   TIME(threshold1) += HALF_PERIOD;
00532   TIME(queue->th2) += HALF_PERIOD;
00533   TIME(queue->th3) += HALF_PERIOD;
00534 
00535   threshold1_time = TIME(threshold1);
00536   event = NEXT_HOR(threshold1);
00537   while(TIME(event) <= threshold1_time) {
00538     NEXT_HOR(threshold1) = NEXT_HOR(event);
00539     temp = event;
00540     while (NEXT_BOT(temp) != temp) {
00541       InsertInBin(wheel,temp);
00542       temp = NEXT_VER(temp);
00543     }
00544     InsertInBin(wheel,temp);
00545     event = NEXT_HOR(threshold1);
00546   }
00547 
00548 } /* End of HouseKeeping */
00549 
00550 
00560 static void
00561 InsertFanouts(
00562   Ntk_Node_t *node,
00563   st_table *fanoutTable)
00564 {
00565   int i;
00566   Ntk_Node_t *fanout;
00567   
00568   Ntk_NodeForEachFanout(node,i,fanout) {
00569     st_insert(fanoutTable,(char *)fanout,(char *)0);
00570   }
00571 
00572 } /* End of InsertFanouts */
00573 
00574 
00585 static void
00586 PerformSecondPass(
00587   Ntk_Network_t *network,
00588   EventQueue *queue,
00589   st_table *fanoutTable)
00590 {
00591   bdd_manager *ddManager = Ntk_NetworkReadMddManager(network);
00592   graph_t *partition = Part_NetworkReadPartition(network);
00593   st_table *nodeToSimTable = TruesimNetworkReadSimTable(network);
00594   st_generator *stGen;
00595   Ntk_Node_t *node,*dummy;
00596   char next,prev;
00597 
00598   st_foreach_item(fanoutTable,stGen,&node,&dummy) {
00599     TrueSim_t *sim;
00600 
00601     /* Lookup the simtable to extract the sim struct for the gate. */
00602     if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00603       (void) fprintf(vis_stderr,"** truesim fatal: In PerformSecondPass\n");
00604       (void) fprintf(vis_stderr,"        Sim. structure missing for %s\n",
00605                      Ntk_NodeReadName(node));
00606       assert(0);
00607     }
00608 
00609     next = TruesimEvaluateNode(node,partition,ddManager,
00610                                nodeToSimTable);
00611     prev = sim->value;
00612     if (prev != next) {
00613       /* Check if an event already exists. If true, then reschedule the event */
00614       if (sim->event) {
00615         RescheduleEvent(queue,node,sim,next);
00616       } else {
00617         ScheduleEvent(queue,node,sim,next);
00618       }
00619     } else {
00620       /* Check if an event already exists. If true, then cancel that event */
00621       if (sim->event)
00622         CancelEvent(queue,sim);
00623     }
00624   }
00625 
00626 } /* End of PerformSecondPass */
00627 
00628 
00638 static void
00639 ScheduleEvent(
00640   EventQueue *queue,
00641   Ntk_Node_t *node,
00642   TrueSim_t *sim,
00643   char value)
00644 {
00645   Event *event;
00646 
00647   EVENT_ALLOC(queue, event);
00648   TIME(event) = queue->time + (long) sim->delay;
00649   GATE(event) = node;
00650   TYPE(event) = (value == '1') ? SIM_EVENT_1 : SIM_EVENT_0;
00651   NEXT_HOR(event) = NIL(Event);
00652   NEXT_VER(event) = NIL(Event);
00653   NEXT_BOT(event) = NIL(Event);
00654 
00655   InsertInBin(queue->wheel, event);
00656 
00657   /* Cross pointer to the event, in case of cancellation or rescheduling */
00658   sim->event = event;
00659   numEvents++;
00660 
00661 } /* End of ScheduleEvent */
00662 
00663 
00673 static void
00674 RescheduleEvent(
00675   EventQueue *queue,
00676   Ntk_Node_t *node,
00677   TrueSim_t *sim,
00678   char value)
00679 {
00680   Event *event;
00681 
00682   event = sim->event;
00683   TYPE(event) = SIM_EVENT_C;
00684 
00685   ScheduleEvent(queue,node,sim,value);
00686 
00687 } /* End of RescheduleEvent */
00688 
00689 
00699 static void
00700 CancelEvent(
00701   EventQueue *queue,
00702   TrueSim_t *sim)
00703 {
00704   Event *event;
00705 
00706   event = sim->event;
00707   TYPE(event) = SIM_EVENT_C;
00708 
00709   sim->event = NIL(Event);
00710 
00711 } /* End of CancelEvent */
00712 
00713 
00728 static void
00729 InsertInBin(
00730   Event **wheel,
00731   Event *event)
00732 {
00733   Event *prev,*curr;
00734   long  pos;
00735 
00736   pos = WHEEL_POS(TIME(event)); 
00737 
00738   if (TIME(wheel[pos]) >= TIME(event)) { /* to insert as first element */
00739     if (TIME(wheel[pos]) > TIME(event)) {
00740       NEXT_BOT(event) = event;
00741       NEXT_HOR(event) = wheel[pos];
00742       NEXT_VER(event) = wheel[pos];
00743       wheel[pos] = event;
00744 
00745     } else {
00746       NEXT_VER(event) = wheel[pos];
00747       NEXT_BOT(event) = NEXT_BOT(NEXT_VER(event));
00748       NEXT_HOR(event) = NEXT_HOR(wheel[pos]);
00749       wheel[pos] = event;
00750 
00751     }
00752   } else {
00753     prev = curr = wheel[pos];
00754 
00755     /* Assumption : the last element in the converging list always has
00756        a time greater than event. This is true by construction. */
00757     while(TIME(curr) < TIME(event)) {
00758       prev = curr;
00759       curr = NEXT_HOR(curr);
00760     }
00761 
00762     if (TIME(curr) == TIME(event)) {
00763       NEXT_VER(event) = curr;
00764       NEXT_BOT(event) = NEXT_BOT(NEXT_VER(event));
00765       NEXT_HOR(event) = NEXT_HOR(curr);
00766       NEXT_HOR(prev) = event;
00767       NEXT_VER(NEXT_BOT(prev)) = event;
00768     } else {
00769       NEXT_BOT(event) = event;
00770       NEXT_HOR(event) = curr;
00771       NEXT_VER(event) = curr;
00772       NEXT_HOR(prev) = event;
00773       NEXT_VER(NEXT_BOT(prev)) = event;
00774     }
00775   }     
00776 
00777 } /* End of InsertInBin */
00778 
00779 
00789 static EventQueue *
00790 InitQueue(void)
00791 {
00792   EventQueue *queue; 
00793   Event **wheel,*threshold; 
00794   int i;
00795 
00796   queue = ALLOC(EventQueue, 1); 
00797   queue->wheel = ALLOC(Event *, WHEEL_SIZE); 
00798   queue->current = NIL(Event);
00799   queue->time = 0;
00800   queue->freeList = NIL(Event *);
00801   queue->nextFree = NIL(Event);;
00802 
00803   /* Allocate control events, th1, th2 and th3 and thi (infinity)*/
00804   EVENT_ALLOC(queue, threshold);
00805   queue->thi = threshold;
00806   TYPE(threshold)  = THRESHOLD_I;
00807   TIME(threshold) = MAX_TIME;
00808   NEXT_HOR(threshold) = NIL(Event);
00809   NEXT_VER(threshold) = NIL(Event);
00810   NEXT_BOT(threshold) = threshold;
00811 
00812   EVENT_ALLOC(queue, threshold);
00813   queue->th1 = threshold;
00814   TYPE(threshold)  = THRESHOLD_1;
00815   TIME(threshold) = PERIOD -1;
00816   NEXT_HOR(threshold) = queue->thi;
00817   NEXT_VER(threshold) = queue->thi;
00818   NEXT_BOT(threshold) = threshold;
00819 
00820   EVENT_ALLOC(queue, threshold);
00821   queue->th2 = threshold;
00822   TYPE(threshold)  = THRESHOLD_2;
00823   TIME(threshold) = PERIOD -1;
00824   NEXT_HOR(threshold) = queue->th1;
00825   NEXT_VER(threshold) = queue->th1;
00826   NEXT_BOT(threshold) = threshold;
00827 
00828   EVENT_ALLOC(queue, threshold);
00829   queue->th3 = threshold;
00830   TYPE(threshold)  = THRESHOLD_3;
00831   TIME(threshold) = PERIOD-1;
00832   NEXT_HOR(threshold) = queue->th1;
00833   NEXT_VER(threshold) = queue->th1;
00834   NEXT_BOT(threshold) = threshold;
00835 
00836   wheel = queue->wheel;
00837   threshold = queue->th1;
00838   for (i = 0; i < WHEEL_SIZE; i++) {
00839     wheel[i] = threshold;
00840   }
00841 
00842   wheel[WHEEL_POS(HALF_PERIOD - 1)] =  queue->th2;
00843   wheel[WHEEL_POS(PERIOD - 1)] =  queue->th3;
00844 
00845   return (queue);
00846 
00847 } /* End of InitQueue */
00848 
00849 
00859 static void
00860 NewPage(EventQueue *queue)
00861 {
00862   Event **mem,*list;
00863   int i;
00864 
00865   mem = (Event **) ALLOC(char,MEM_CHUNK * sizeof(Event) + sizeof(Event *));
00866 
00867   mem[0] = (Event *) queue->freeList;
00868   queue->freeList = mem;
00869 
00870   list = (Event *) &mem[1];
00871 
00872   i = 0;
00873   do {
00874     list[i].horizontal = &list[i + 1];
00875   } while (++i < MEM_CHUNK -1);
00876 
00877   list[MEM_CHUNK - 1].horizontal = NIL(Event);
00878 
00879   queue->nextFree = list;
00880 
00881 } /* End of NewPage */
00882 
00883 
00893 static enum st_retval
00894 stTrueSimFree(
00895   char *key,
00896   char *value,
00897   char *arg)
00898 {
00899   TrueSim_t *sim;
00900   sim = (TrueSim_t *)value;
00901 
00902   if (sim)
00903     FREE(sim);
00904 
00905   return (ST_CONTINUE);
00906 } /* End of stTrueSimFree */
00907