/**************************** seize ****************************** seize(Simulation sim, Queue queueTeller, Server serverTeller) Purpose: Seizes a widget from the queue. Parameters: I Simulation sim // current sim we are running I Queue queueTeller // current queue // either queue1 or queue2 I Server serverTeller // current server // either server1 or server2 Returns: Does not return anything fuctionally, but does insert the newly created server1 or server2 complete event into the linked list. Notes: 1. Uses removeQ function *****************************************************************/ void seize(Simulation sim, Queue queueTeller, Server serverTeller) { QElement fill; // element returned from removeQ Event event; // Server complete event int iWaitTime; // The wait time for each widget in the queue // checks to see if widget is busy if(serverTeller->bBusy == FALSE) { // if not busy // remove widget from queue if(removeQ(queueTeller, &fill)) { iWaitTime = (sim->iClock - fill.iEnterQTime); // wait is equal to current clock time minus the time the widget // enters the system if(sim->bVerbose == TRUE) { printf("%4d %6ld Leave %s Waited: %d\n", sim->iClock, fill.widget.lWidgetNr, queueTeller->szQName, iWaitTime); printf("%4d %6ld Seized %s\n", sim->iClock, fill.widget.lWidgetNr, serverTeller->szServerName); } // set server to be busy serverTeller->bBusy = TRUE; //create completion event for server event.widget = fill.widget; if(sim->cRunType == 'A') { //checks to see whether it is server 1 or 2 to set event type and event time properly if(strcmp(serverTeller->szServerName, "Server 1") == 0) { event.iEventType = EVT_SERVER1_COMPLETE; event.iTime = sim->iClock + fill.widget.iStep1tu; } else if(strcmp(serverTeller->szServerName, "Server 2") == 0) { event.iEventType = EVT_SERVER2_COMPLETE; event.iTime = sim->iClock + fill.widget.iStep2tu; } } else // for alternative b and c - only have 1 server that completes both step1 and step2 { event.iEventType = EVT_SERVER1_COMPLETE; event.iTime = (sim->iClock + fill.widget.iStep1tu + fill.widget.iStep2tu); } queueTeller->lQueueWaitSum += iWaitTime; // add the wait time for each widget to the total wait sum queueTeller->lQueueWidgetTotalCount++; // increment queue count by one each time you seize a widget // inserts the event into the list insertOrderedLL(sim->eventList, event); } } }
/****************************** seize ****************************************** void seize(Simulation sim, Queue queue, Server server) Purpose: Handles the seize event for a given server. In this case, take the top element out of the given queue while updating the queue stats, insert the widget in the given server and mark the server busy, and insert a new event in the simulation's event list representing the widget exiting the server. This function also prints the different steps of the event if verbose mode was activated. Parameters: I Simulation sim Simulation running the event. I/O Queue queue Queue to remove the widget from. I/O Server server Server to insert the widget in, also the server to give its name to the newly created server completion event. Returns: queue parm - the queue to remove the widget from. server parm - the server to insert the widget in. Notes: *******************************************************************************/ void seize(Simulation sim, Queue queue, Server server) { if (server->bBusy == FALSE && queue->pHead != NULL) //if server is free and there's something in the queue { //take top element out of queue and add its wait time to the sum QElement element; removeQ(queue, &element); long lQWaitTime = sim->iClock - element.iEnterQTime; queue->lQueueWaitSum += lQWaitTime; printEvent(sim, " %6d %8ld %s %s%s %ld", sim->iClock, element.widget.lWidgetNr, "Leave", queue->szQName, ", waited", lQWaitTime); //put widget taken out of queue into the server and mark it busy server->widget = element.widget; server->bBusy = TRUE; printEvent(sim, " %6d %8ld %s %s", sim->iClock, element.widget.lWidgetNr, "Seized", server->szServerName); //create a SERVER_COMPLETE event for the widget and place it into the event list Event event; event.widget = server->widget; if (strcmp(server->szServerName, "Server 1") == 0) { if (sim->cRunType == 'A') { //altA only spends step1 in server 1 event.iTime = sim->iClock + event.widget.iStep1tu; } else { //altB and current spend both step 1 and step 2 in server 1 event.iTime = sim->iClock + event.widget.iStep1tu + event.widget.iStep2tu; } event.iEventType = EVT_SERVER1_COMPLETE; } if (strcmp(server->szServerName, "Server 2") == 0) { event.iTime = sim->iClock + event.widget.iStep2tu; event.iEventType = EVT_SERVER2_COMPLETE; } insertOrderedLL(sim->eventList, event); } }
void roundRobin(int map[N][5],int proc_count,char filename[]) { QUEUE q; int cur_time=0; int new_proc[N]; int i,k,quantum_used,p,temp,c,cpu_util=0; int blocked[N]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; int turn_around[N]; int proc_added=0; q.rear=q.front=-1; FILE *fp=fopen(filename,"w"); fclose(fp); while(1) { int process_state[N]={0}; k=0; for(i=0;i<proc_count;i++) { if(cur_time==map[i][3]) { new_proc[k++]=i; proc_added++; } } for(i=0;i<proc_count;i++) { if(blocked[i]==cur_time) { new_proc[k++]=i; blocked[i]=-1; } } sort_proc(new_proc,k); for(i=0;i<k;i++) insertQ(&q,new_proc[i]); if(q.rear!=q.front) { p=peekFront(q); process_state[p]=1; cpu_util++; quantum_used=(quantum_used+1)%2; map[p][4]++; if(map[p][4]==map[p][1]) { removeQ(&q); quantum_used=0; turn_around[p]=cur_time; } if(quantum_used==0 && map[p][4]!=map[p][1] && map[p][4]!=(map[p][1])/2) { p=removeQ(&q); quantum_used=0; insertQ(&q,p); } if(map[p][4]==(map[p][1])/2) { p=removeQ(&q); quantum_used=0; blocked[p]=map[p][2]+cur_time+1; } } temp=q.front; while(temp!=q.rear) { temp=(temp+1)%N; if(q.arr[temp]!=p) process_state[q.arr[temp]]=2; } for(i=0;i<proc_count;i++) { if(blocked[i]!=-1 && i!=p) { process_state[i]=3; } } printProcessStateToFile(filename,process_state,proc_count,cur_time); c=checkBlocked(blocked,proc_count); if(q.front==q.rear && c && proc_added==proc_count) break; cur_time++; p=-1; } fp=fopen(filename,"a"); fprintf(fp,"\n"); fprintf(fp,"Finishing Time : %d\n",cur_time); fprintf(fp,"CPU utilization : %3.2f\n",(float)cpu_util/(cur_time+1)); for(i=0;i<proc_count;i++) { temp=turn_around[i]-map[i][3]+1; fprintf(fp,"Turnaround process %d : %d\n",i,temp); } fclose(fp); }
/* Running time of algorithm ================================================================= struct digraph - int *inDegree; - 4 bytes * n - int nVertices; - 4 bytes - ListEDGE *L; - 4 bytes * n ListEDGE ---------------------------------------------------------- nodeEdgeType *head; (data, next) 8 bytes * n int size; (outdegree) 4 bytes * (1 to n) Total =============================================================== n+m = 8n + 4 + + 8n + 4(n-1) = 20n = O(n) Matrix = O(n^2) Therefore, this graph representation is much better for sparse digraph - A single link list will speed up runtime at the expense of writing more difficult functions - nEdge s is not within the struct will save 4 bytes in exchange for a longer calculation in the indegree function - */ int topological_sort( DiGraph DG ) { int Lcount = 0; vertex x, tempResult; Tqueue *Q; Q = (Tqueue*) malloc(sizeof(Tqueue)); if (Q == NULL || DG == NULL) { return -1; } else { vertex D[DG -> nVertices]; //array of integers indexed by the vertices - in degree array vertex L[DG -> nVertices]; //sorted link list of vertices /* Compute the in-degrees D[x] of the vertices in DG */ for (x = 0; x < DG -> nVertices; x++) //for vertices { D[x] = 0; //initialize D L[x] = -1; //initialize L } for (x = 0; x < DG -> nVertices; x++) //for vertices { nodeEdgeType *temp = DG -> L[x].head; while (temp) //while there is a successor { ++D[temp -> data]; temp = temp -> next; } } /* Initialize queue Q */ initialize(Q); for (x = 0; x < DG -> nVertices; x++) //for vertices { //enqueue any vertices with indegree 0 if ( D[x]==0 ) // insert x into Q { tempResult = insertQ(x, Q); } } while (isEmpty(Q) != 1) // while Q not empty { tempResult = removeQ(Q, &x);//dequeue x from Q (top) L[Lcount] = x;//insert x to list ++Lcount; int w; for (w = 0; w < DG -> L[x].size; w++) //for each successor DG -> L[x].size { --D[w]; //Indegree of vertex w if ( D[w]== 0 ) //enqueue w into Q { tempResult = insertQ(w, Q); } } } //check if all the vertices got transfered to the list (no cycles?) //if (Lcount == DG -> nVertices) printf("topological order ->"); int p; for (p = 0; p < Lcount; p++) { printf("[%i], ", L[p]); } printf("THE SIZE IS %i\n", Lcount); if (Lcount== DG -> nVertices && Lcount != 0) { return 1; } else //cyclic { return 0; } } }