/* File: evQ.c */ /* ********************************************************************* ALTERNATING BIT AND GO-BACK-N NETWORK EMULATOR Revised version of code by J.F. Kurose From the companion website for _Computer Networking: A Top-Down Approach Featuring the Internet_ by J.F. Kurose and K. W. Ross (c) 2001 by Addison Wesley Longman Based on document at (as of 02 July 2002) ********************************************************************* */ #include static char * event_type(int, char *, int); static char * entity_name(int, char *, int); /*-----------------------*/ /* generate_next_arrival */ /* *-----------------------------------------*/ /* */ /*-----------------------------------------------------------------*/ void generate_next_arrival(void) { float x; struct event *evptr; const char *proc="generate_next_arrival"; if (TRACE>2) { fprintf(TRACEOUT, "%*sGENERATE NEXT ARRIVAL: creating new arrival\n", INDENT, ""); } x = lambda*jimsrand()*2.0; /* x is uniform over [0, 2*lambda] */ /* with mean of lambda */ evptr = malloc(sizeof(struct event)); if (NULL != evptr) { evptr->evtime = KRtime + x; evptr->evtype = FROM_LAYER5; if ( BIDIRECTIONAL && (jimsrand()>0.5) ) { evptr->eventity = Server; } else { evptr->eventity = Client; } insertevent(evptr); } else { swerr(proc, 1, "out of memory from malloc()\n"); } } /* generate_next_arrival() */ /*-------------*/ /* insertevent */ /* *---------------------------------------------------*/ /* */ /*-----------------------------------------------------------------*/ void insertevent(struct event *p) { struct event *q,*qold; if (TRACE>2) { fprintf(TRACEOUT, "%*sINSERTEVENT: time is %f\n", INDENT+2, "", KRtime); fprintf(TRACEOUT, "%*sINSERTEVENT: future time will be %f\n", INDENT+2, "", p->evtime); } q = evlist; /* q points to header of list in which p struct inserted */ if (NULL==q) { /* list is empty */ evlist=p; p->next=NULL; p->prev=NULL; } else { for (qold = q; q !=NULL && p->evtime > q->evtime; q=q->next) { qold=q; } if (NULL==q) { /* end of list */ qold->next = p; p->prev = qold; p->next = NULL; } else if (q==evlist) { /* front of list */ p->next=evlist; p->prev=NULL; p->next->prev=p; evlist = p; } else { /* middle of list */ p->next=q; p->prev=q->prev; q->prev->next=p; q->prev=p; } } } /* insertevent() */ /*-------------*/ /* printevlist */ /* *---------------------------------------------------*/ /* */ /*-----------------------------------------------------------------*/ void printevlist(void) { struct event *q; char name[500]; printf("Event List: \n"); printf("---------------------------------------------------------\n"); printf("Event time Entity Event type \n"); printf("---------------- ----------- ----------------------------\n"); for(q=evlist; NULL!=q; q=q->next) { printf("%16.7f ", q->evtime); printf("#%d (%.22s) ", q->eventity, entity_name(q->eventity, name, (int)sizeof(name))); printf("#%d (%s) ", q->evtype, event_type(q->evtype,name,(int)sizeof(name))); printf("\n"); } printf("---------------------------------------------------------\n"); printf("---------------------------------------------------------\n"); } /* printevlist() */ static char * entity_name(int entity, char * name, int namelen) { switch (entity) { case Client: strncpy(name, "Client", namelen); break; case Server: strncpy(name, "Server", namelen); break; default: strncpy(name, "**?!**", namelen); } return name; } /* entity_name() */ static char * event_type(int event, char *name, int namelen) { static char* type[] = { "** No Such Event **", "Timer Interrupt", "Down from App. layer", "Up from N/W layer", "Dummy timer event" }; if ((unsigned)event > sizeof type/sizeof type[0]) { strncpy(name, type[0], namelen); } else { strncpy(name, type[event], namelen); } return name; } /* event_type() */ /* EOF (evQ.c) */