/* file: event.c */ /* * Tom Laramee * HW #3 - event.c file for Wireless LAN sim of MAC protocol * * event.c file - (esentially supplied by TA from last year) * (I only modified the free_procrec function) * */ #include "event.h" #include "main.h" /***********************************************************************/ /* alloc_procrec(): allocates the memory for a proc record and returns */ /* a pointer to the uninitialiazed proc record */ /***********************************************************************/ struct proc *alloc_procrec(void) { struct proc *procptr; procptr = (struct proc *) malloc(sizeof(struct proc)); /* get mem for event receord */ if (procptr==NULL) { printf("PANIC: No free memory\n"); exit(-1); } procptr->jobid = -1; procptr->local_arrival_time = -1; procptr->sys_arrival_time = -1; procptr->next = procptr->prev = NULL; return(procptr); } /***********************************************************************/ /* free_procrec(): free the memory associated with a proc. record */ /* procptr is a pointer to the proc record whose memory */ /* is to be deallocated, */ /***********************************************************************/ void free_procrec(struct proc *procptr) { if (procptr==NULL) fatal ("free_procrec", "cannot free a pointer to NULL"); free(procptr); } /**************************************************************************/ /* get_firstproc(queue): return pointer to proc rec for the first (oldest)*/ /* proc. at the queue. The proc record is unlinked from the head */ /* of the appropriate list !!!!!!!!! */ /**************************************************************************/ struct proc *get_firstproc(int q_id) { struct proc *p,*psav; p = qptr[q_id]; if (p!=NULL) { qptr[q_id] = p->next; if (qptr[q_id] != NULL) qptr[q_id]->prev = NULL; } else { printf("REM_PROC: Illegal job removeal attempted. no jobs queued\n"); printf("Queue was %d\n",q_id); exit(-1); } return(p); } /************************************************************************/ /* get_nextevent(): return a ptr to the event record for the next event */ /* IMPORTANT: the event record is also unlinked from the head */ /* of the event list !!!!!!!!! */ /************************************************************************/ struct event *get_next_event(void) { struct event *evsave; if (evList==NULL) fatal("get_next_event", "there is no next event; event list is empty"); evsave = evList; evList = evList->next; if (evList!=NULL) evList->prev=NULL; /* remove event from event list */ return(evsave); } /*************************************************************************/ /* alloc_evrec(): allocates the memory for an event record and returns */ /* a pointer to the uninitialiazed event record */ /*************************************************************************/ struct event *alloc_evrec(void) { struct event *evptr; evptr = (struct event *) malloc(sizeof(struct event)); /* get mem for event receord */ if (evptr==NULL) fatal("alloc_evrec", "No memory for allocation"); evptr->evtime = -1; evptr->evcode = -1; evptr->nodecode = -1; evptr->jobdest = -1; evptr->next = evptr->prev = NULL; return(evptr); } /***********************************************************************/ /* free_evrec(): free the memory associated with an event record */ /* evptr is a pointer to the event record whose memory */ /* is to be deallocated, */ /***********************************************************************/ void free_evrec(struct event *evptr) { if (evptr==NULL) fatal ("free_evrec", "Cannot free memory which isn't used"); free(evptr); } /********************************************************************/ /* basic event list handling routines */ /********************************************************************/ void insertevent(struct event *p) { struct event *q,*qold; q = evList; /* q points to header of list in which p struct inserted */ if (q==NULL) { /* 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 (q==NULL) { /* 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; } } } /************************************************************************/ /* insertproc(procptr,queue) insert the record pointed to by proc into */ /* into the queue specified by the integer parameter queue */ /* Insertion at the end of the list and removal from the from of the */ /* list implies FCFS service at all queues. */ /************************************************************************/ void insertproc(struct proc *procptr, int q_id) { struct proc *p; procptr->next = procptr->prev = NULL; p = qptr[q_id]; if (p==NULL) qptr[q_id]=procptr; else { while (p->next != NULL) p = p->next; p->next = procptr; procptr->prev = p; } } /********************************************************************/ /* Utility for generating a random number */ /********************************************************************/ double uni(void) /* Generate a random number from Unif(0,1) */ { int a, b; a = (int) (iseed / 16384); b = (int) (iseed % 16384); iseed = (((13205*a + 74505*b) % 16384)*16384 + 13205*b) % 268435456; return( (double) iseed / 268435456) ; } /*********************************************************************/ /* Utility for generating next arrival time using poisson dist */ /*********************************************************************/ void nextarrival( void ) /* Compute the poisson distribution of the next arrival according to * the arrival rate of lambda and set the global variable next to be * the time at which the next event occurs */ { double deltat, ln; ln = log( 1-uni() ); deltat = -( ln ) / lambdaN; timeNextEvent = sysTime + deltat; }