void fn3(void *args) { int *n = (int*)args; printQueues(); printf("\nExecuting F3, ready queue id: %d\n", ready_queue->id); printf("\n The Argument Obtained is: %d", args); MySemaphoreSignal(sem1); temp = getSemaphoreFromId(sem1.semaphoreId); printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); MySemaphoreSignal(sem2); temp = getSemaphoreFromId(sem2.semaphoreId); printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); MySemaphoreSignal(sem1); temp = getSemaphoreFromId(sem1.semaphoreId); printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); MySemaphoreSignal(sem2); temp = getSemaphoreFromId(sem2.semaphoreId); printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); MySemaphoreSignal(sem2); temp = getSemaphoreFromId(sem2.semaphoreId); printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); MySemaphoreSignal(sem2); temp = getSemaphoreFromId(sem2.semaphoreId); printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); MySemaphoreSignal(sem2); temp = getSemaphoreFromId(sem2.semaphoreId); printf("\nF3 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); printQueues(); }
void MySemaphoreWait(MySemaphore semaphore) { /*The counter of S is positive In this case, the counter is decreased by 1 and the thread resumes its execution. The counter of S is zero In this case, the thread is suspended and put into the private queue of S.*/ MySemaphore* sem = getSemaphoreFromId(semaphore.semaphoreId); //capture the context here (1) printf("\nTP1"); ucontext_t currentContext; getcontext(¤tContext); printf("\nTP1"); printf("\n Semaphore Id: %d", sem->semaphoreId); printf("\n Semaphore Value: %d", sem->semaphoreValue); sem->semaphoreValue--; if (sem->semaphoreValue >= 0) //Verify once, if Semaphore value change from 1 to 0 allows the execu return; //the semaphore is free for access printf("\nTP2"); printQueues(); printf("\n Semaphore Value: %d", sem->semaphoreValue); printQueues(); if(ready_queue == NULL) { setcontext(&controller); } if (ready_queue != NULL) { printf("\nTP2"); printf("\nTP2"); ready_queue->semaphoreBlocked = sem->semaphoreId; MyThread* trav = ready_queue->next; MyThread* temp = ready_queue; printf("\nTP3"); insertIntoSemaphoreBlockedQueue(ready_queue); ready_queue->context = currentContext; ready_queue->next = NULL; ready_queue = trav; //printf("\n Printing the Queues from Thread Join: "); //printQueues(); if(ready_queue != NULL) setcontext(&ready_queue->context); //Put the context captured at (1) into the blockedSemaphoreQueue } }
int fn1() { int n = 10; printf("\nExecuting F1, ready queue id: %d\n", ready_queue->id); printf("\n N = %d", n); printf("\n &N = %d", &n); sem1 = MySemaphoreInit(2); sem2 = MySemaphoreInit(0); printf("CPAfterSemaphoreCreation"); printQueues(); printf("\nGetting SemaphoreId: %d",sem1.semaphoreId); temp = getSemaphoreFromId(sem1.semaphoreId); printf("\nF2 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); temp = getSemaphoreFromId(sem2.semaphoreId); printf("\nF2 Semaphore ID: %d has Value: %d", temp->semaphoreId,temp->semaphoreValue); child2 = MyThreadCreate((void*)fn2, &n); child2 = MyThreadCreate((void*)fn2, &n); child2 = MyThreadCreate((void*)fn3, &n); child2 = MyThreadCreate((void*)fn2, &n); printf("\nthis is from 1_1\n"); printf("\n Joining the threads: parent %d(won't run again), child %d", ready_queue->id, child2.id); MyThreadJoinAll(); printf("\nthis is from 1_2\n"); printf("If printed, %d has joined successfully", ready_queue->id); }
void MyThreadInit(void(*start_funct)(void *), void *args) { start = 1; MyThread* node; //printf("\nCP1"); ready_queue = malloc(sizeof(MyThread)); getcontext(&ready_queue->context); ready_queue->context.uc_link=&controller; ready_queue->context.uc_stack.ss_sp=malloc(MEM); ready_queue->context.uc_stack.ss_size=MEM; ready_queue->context.uc_stack.ss_flags=0; ready_queue->id = threadCount++; //printf("Allocation Initial Id: %d", ready_queue->id); makecontext(&ready_queue->context, (void*)start_funct, 1, (int)args); ucontext_t next; int id; getcontext(&controller); //printf("\nAbout to Start Checking of Unblocking"); //printQueues(); CheckForUnblocking(); //printf("\nChecked for Block"); //printQueues(); if(ready_queue != NULL) { if(start == 1) { next = ready_queue->context; id = ready_queue->id; //printf("\n 2 Should Repeat:"); //printf("\n4Allocation Initial Id: %d", ready_queue->id); start = 0; //printQueues(); setcontext(&next); } else if (ready_queue->next != NULL) { ready_queue = ready_queue->next; //CheckForUnblocking(); next = ready_queue->context; id = ready_queue->id; //printf("\n 2 Should Repeat:"); //printf("\nSetting Context Id: %d",id); //printQueues(); setcontext(&next); } else { //printf("1Entering New Code"); ready_queue = NULL; //printf("2Entering New Code"); //printQueues(); CheckForUnblocking(); //printf("1Entering New Code"); if (ready_queue != NULL) { next = ready_queue->context; id = ready_queue->id; //printf("\n 2 Should Repeat:"); //printf("\nSetting Context Id: %d",id); //printQueues(); setcontext(&next); } } } printf("completed\n"); printQueues(); printf("Final Queue Remains: "); MySemaphoreDestroy(sem1); MySemaphoreDestroy(sem2); printQueues(); }
void CheckForUnblocking() { int isReadyEmpty = 0; if(ready_queue == NULL) isReadyEmpty = 1; printf("\nStarting Checking of Unblocking"); int i; int flag = 0; printQueues(); //getting segmentation fault here, need to check further - only for the last blocked thread. printf("CP1"); if(blocked_queue == NULL) return; printf("CP2"); MyThread* trav = blocked_queue; MyThread* temp; flag = 0; for(i=0; i<ARR_SIZE; i++) { if(trav->blockedFor[i] == 0) break; if(presentInReadyQueue(trav->blockedFor[i])) { flag = 1; printf("\nFlagged 1"); break; } if(presentInSemaphoreBlockedQueue(trav->blockedFor[i])) { //printQueues(); flag = 1; printf("\nFlagged 1"); //printQueues(); break; } } printf("CP3"); if(flag == 0) { blocked_queue = blocked_queue->next; printf("\n Before inserting to ready queue: %d", trav->id); insertIntoReadyQueue(trav); if(blocked_queue == NULL) { printf("\nUnblocking Last Node at Head: %d", trav->id); if(isReadyEmpty == 1) { printf("Yayy! it works!"); setcontext(&ready_queue->context); } return; } } MyThread* prev = blocked_queue; trav = blocked_queue; while(trav != NULL) { flag = 0; for(i=0; i<ARR_SIZE; i++) { if(trav->blockedFor[i] == 0) break; if(presentInReadyQueue(trav->blockedFor[i])) { flag = 1; break; } if(presentInSemaphoreBlockedQueue(trav->blockedFor[i])) { //printQueues(); flag = 1; printf("\nFlagged 1"); //printQueues(); break; } } if(flag == 0) { //printf("Before Inserting - id: %d", trav->id); temp = trav; if(prev == trav) { blocked_queue = blocked_queue->next; prev = blocked_queue; trav = blocked_queue; } else { trav = trav->next; } trav->next = trav->next->next; insertIntoReadyQueue(temp); //printf("Inserted Node"); //printf("\nUnblocking Node: %d", temp->id); } else { prev = trav; trav = trav->next; } } if(isReadyEmpty == 1) { printf("Yayy! it works!"); setcontext(&ready_queue->context); } }
/* * Simulates a multilevel feedback queue cpu scheduling algorithm * TODO Update the file parsing to be smarter and provide documentation */ int main(int argc, char** argv) { const int FIELD_LENGTH = 1024; //Default string allocation char line[FIELD_LENGTH]; //Buffer for line reading of master file char* sub_out; //Output of substring checks for certain fields int read_T1 = 0; //0 if T1 hasnt been read yet int read_T2 = 0; //0 if T2 hasnt been read yet int T1, T2; //Time Quantums int processCount = 0; //Number of processes read from the file int processCompleted = 0; //Counter for number of process completed Queue* futureProcesses = new_queue(0); //Queue of all the processes that havent technically been submitted yet Queue* completed = new_queue(-1); //Queue of all completed processes, for output of averaging at the end int i; //Open the file passed in as the only argument to the program FILE* master_file = fopen(argv[1], "rt"); if (master_file == 0) { fprintf(stderr, "Failed to open %s\n", argv[1]); exit(1); } //Open output file for logging functions of the simulator FILE* out_file = fopen("cpu_output.txt", "w"); fprintf(out_file, "############################################################\n"); fprintf(out_file, "Logging for Multi-Level Queue Scheduling Simulation Started!\n"); fprintf(out_file, "############################################################\n\n"); //Read in the file and create necessary process objects if (master_file != NULL) { //Read line by line to get T1 and T2 while (fgets(line, FIELD_LENGTH, master_file) != NULL) { if (strcmp(line, "\n") == 0) { //SKIP NEW LINES IN THE FILE } else { //Change the line to all lowercase array_to_lower(line); //Read in TQ#1 and TQ#2 if (!read_T1) { sub_out = strstr(line, "time quantum 1:"); if (sub_out != NULL) { read_T1 = 1; T1 = get_num(sub_out); } } else if (!read_T2) { sub_out = strstr(line, "time quantum 2:"); if (sub_out != NULL) { read_T2 = 1; T2 = get_num(sub_out); break; } } } } //Initialize a CPU CPU* cpu = new_cpu(T1, T2); //Read in the rest of the file and create all processes and their associated bursts while (fgets(line, FIELD_LENGTH, master_file) != NULL) { if (strcmp(line, "\n") == 0) { //SKIP NEW LINES IN THE FILE } else { //Change the line to all lowercase array_to_lower(line); Process* end = get_end(futureProcesses); //Get the process id and create a new process for it sub_out = strstr(line, "process id:"); if (sub_out != NULL) { int id = get_num(sub_out); Process* process = new_process(id); if (end != NULL) { end->next = process; } else { futureProcesses->processes = process; } processCount++; } //Get the arrival time of the most recently created process sub_out = strstr(line, "arrival time:"); if (sub_out != NULL) { int arrival = get_num(sub_out); end->arrival_time = arrival; } //Create a cpu burst of the recently created process sub_out = strstr(line, "cpu burst:"); if (sub_out != NULL) { int length = get_num(sub_out); Burst* cpu_burst = new_cpu_burst(length); Burst* burst_end = get_last_burst(end); if (burst_end != NULL) { burst_end->next_burst = cpu_burst; } else { end->bursts = cpu_burst; } } //Create a i/o burst for the recently created process sub_out = strstr(line, "i/o burst:"); if (sub_out != NULL) { int length = get_num(sub_out); Burst* io_burst = new_io_burst(length); Burst* burst_end = get_last_burst(end); if (burst_end != NULL) { burst_end->next_burst = io_burst; } else { end->bursts = io_burst; } } //Set the device id for the recently created i/o burst sub_out = strstr(line, "i/o device id:"); if (sub_out != NULL) { int id = get_num(sub_out); Burst* burst_end = get_last_burst(end); if (burst_end != NULL) { burst_end->device_num = id; } else { end->bursts->device_num = id; } } } } fclose(master_file); //Handle if no processes are read in if (processCount == 0) { fclose(out_file); fprintf(stderr, "Zero processes were read in.\nThis could be correct or an error in the format of the input file.\nPlease verify that the input file is formatted correctly. \n"); exit(1); } //Run the simulation of the cpu until all processes have been completed while (processCompleted < processCount) { //Go through the list of processes that havent arrived yet Process* tempProc = futureProcesses->processes; Process* lastTemp = NULL; while (tempProc != NULL) { if (tempProc->arrival_time == cpu->time) { //Create a copy of the process to move to the cpu Process* moved = copy_process(tempProc); fprintf(out_file, "Time: %-5d\tProcess#%d Arrived\n", cpu->time, moved->id); if (moved->bursts->type == 1) { //Initial burst is cpu printf("NEW PROCESS CPU FIRST\n"); fprintf(out_file, "Time: %-5d\tInitial burst of Process#%d is a CPU burst\n", cpu->time, moved->id); if (cpu->idle == 1) { //If nothing is running on the cpu fprintf(out_file, "Time: %-5d\tCPU was found to be idle, running process on CPU\n", cpu->time); moved->state = 1; cpu->current_process = moved; cpu->idle = 0; cpu->queue = 1; printQueues(out_file, cpu); } else { //If cpu is occupied put new process in Q1 fprintf(out_file, "Time: %-5d\tCPU was found to be busy, putting process in Q1\n", cpu->time); Process* end = get_end(cpu->Q1); moved->state = 2; if (end != NULL) { //If Stuff is already in Q1 end->next = moved; } else { //If nothing is in Q1 cpu->Q1->processes = moved; cpu->Q1->isEmpty = 0; } printQueues(out_file, cpu); } } else { //Initial burst is I/O printf("NEW PROCESS I/O FIRST\n"); Burst* i_burst = moved->bursts; int device = i_burst->device_num; IODevice* devQ; switch (device) { case 1: //Next burst is on D1 devQ = cpu->D1; break; case 2: //Next burst is on D2 devQ = cpu->D2; break; case 3: //Next burst is on D3 devQ = cpu->D3; break; case 4: //Next burst is on D4 devQ = cpu->D4; break; case 5: //Next burst is on D5 devQ = cpu->D5; break; } //Move the process to the correct i/o device fprintf(out_file, "Time: %-5d\tInitial burst of Process#%d is a I/O burst on device %d\n", cpu->time, cpu->current_process->id, devQ->id); Process* io_end = get_io_proc_end(devQ); if (io_end != NULL) { io_end->next = moved; } else { fprintf(out_file, "Time: %-5d\tProcess#%d running on I/O Device Queue %d\n", cpu->time, cpu->current_process->id, devQ->id); devQ->processes = moved; } printQueues(out_file, cpu); } //Remove the process from futureProcesses if (lastTemp != NULL) { //This wasnt the first lastTemp->next = tempProc->next; tempProc = lastTemp->next; } else { //Process was the first or only in future list futureProcesses->processes = tempProc->next; tempProc = futureProcesses->processes; } } else { //Times not equal get next process in list lastTemp = tempProc; tempProc = tempProc->next; } } //Increment running process time on cpu and decrement its remaining time //If remaining time is 0, if last burst move process to completed otherwise move it to correct i/o queue if (cpu->idle == 0) { printf("CPU NOT IDLE\n"); Burst* burst = get_next_incomplete_burst(cpu->current_process); if (burst != NULL) { printf("NEXT BURST IS NOT NULL\n"); burst->time_active++; burst->time_remaining--; if (burst->time_remaining == 0) { //Burst is complete printf("BURST COMPLETE\n"); burst->completed = 1; fprintf(out_file, "Time: %-5d\tCPU burst of Process#%d completed\n", cpu->time, cpu->current_process->id); if (burst->next_burst != NULL) { printf("MORE BURSTS\n"); int device = burst->next_burst->device_num; IODevice* devQ; switch (device) { case 1: //Next burst is on D1 devQ = cpu->D1; break; case 2: //Next burst is on D2 devQ = cpu->D2; break; case 3: //Next burst is on D3 devQ = cpu->D3; break; case 4: //Next burst is on D4 devQ = cpu->D4; break; case 5: //Next burst is on D5 devQ = cpu->D5; break; } //Move the process to the correct i/o device fprintf(out_file, "Time: %-5d\tProcess#%d moved to I/O Device Queue %d\n", cpu->time, cpu->current_process->id, devQ->id); Process* io_end = get_io_proc_end(devQ); cpu->current_process->next = NULL; if (io_end != NULL) { io_end->next = cpu->current_process; } else { fprintf(out_file, "Time: %-5d\tProcess#%d running on I/O Device Queue %d\n", cpu->time, cpu->current_process->id, devQ->id); devQ->processes = cpu->current_process; } } else { printf("PROCESS COMPLETE\n"); cpu->current_process->state = 0; fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, cpu->current_process->id, cpu->current_process->waiting_cpu, cpu->current_process->waiting_io, (cpu->time - cpu->current_process->arrival_time)); cpu->current_process->completion_t = cpu->time; processCompleted++; Process* end = get_end(completed); if (end != NULL) { //If there are already processes in completed end->next = cpu->current_process; } else { //If this is the first process in completed completed->processes = cpu->current_process; } } //Cpu is empty cpu->current_process = NULL; cpu->idle = 1; cpu->queue = 0; printQueues(out_file, cpu); } } } //Increase cpu wait time for all processes in all 3 queues Process* pq1 = get_end(cpu->Q1); while (pq1 != NULL) { printf("INCREMENTING Q1 WAIT TIMES\n"); pq1->waiting_cpu++; pq1 = pq1->next; } Process* q2 = get_end(cpu->Q2); while (q2 != NULL) { printf("INCREMENTING Q2 WAIT TIMES\n"); q2->waiting_cpu++; q2 = q2->next; } Process* pq3 = get_end(cpu->Q3); while (pq3 != NULL) { printf("INCREMENTING Q3 WAIT TIMES\n"); pq3->waiting_cpu++; pq3 = pq3->next; } //For the first process in each device queue decrement time remaining //If remaining time is 0, if last burst move process to completed otherwise move it to Q1 //Increment waiting time of process moved to front of device queue Process* pd1 = cpu->D1->processes; Process* pd2 = cpu->D2->processes; Process* pd3 = cpu->D3->processes; Process* pd4 = cpu->D4->processes; Process* pd5 = cpu->D5->processes; if (pd1 != NULL) { //Handle running process in device 1 printf("PROCESS IN D1\n"); Burst* bd1 = get_next_incomplete_burst(pd1); if (bd1 != NULL) { printf("D1 PROCESS BURST EXISTS\n"); bd1->time_remaining--; if (bd1->time_remaining == 0) { printf("BURST IN D1 FINISHED\n"); bd1->completed = 1; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd1->id, bd1->device_num); cpu->D1->processes = pd1->next; if (cpu->D1->processes != NULL) { cpu->D1->processes->waiting_io++; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd1->next->id, bd1->device_num); } if (bd1->next_burst != NULL) { printf("MOVING PROCESS FROM D1 to Q1\n"); Process* end_q = get_end(cpu->Q1); fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd1->id); pd1->next = NULL; if (end_q != NULL) { end_q->next = pd1; } else { cpu->Q1->processes = pd1; cpu->Q1->isEmpty = 0; } printQueues(out_file, cpu); } else { printf("PROCESS COMPLETED IN D1\n"); pd1->state = 0; Process* end_completed = get_end(completed); processCompleted++; pd1->completion_t = cpu->time; fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd1->id, pd1->waiting_cpu, pd1->waiting_io, (cpu->time - pd1->arrival_time)); if (end_completed != NULL) { end_completed->next = pd1; } else { completed->processes = pd1; completed->isEmpty = 0; } printQueues(out_file, cpu); } } } } if (pd2 != NULL) { //Handle running process in device 2 printf("PROCESS IN D2\n"); Burst* bd2 = get_next_incomplete_burst(pd2); if (bd2 != NULL) { printf("D2 PROCESS BURST EXISTS\n"); bd2->time_remaining--; if (bd2->time_remaining == 0) { printf("BURST IN D2 FINISHED\n"); bd2->completed = 1; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd2->id, bd2->device_num); cpu->D2->processes = pd2->next; if (cpu->D1->processes != NULL) { cpu->D2->processes->waiting_io++; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd2->next->id, bd2->device_num); } if (bd2->next_burst != NULL) { printf("MOVING PROCESS FROM D2 to Q1\n"); Process* end_q = get_end(cpu->Q1); fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd2->id); pd2->next = NULL; if (end_q != NULL) { end_q->next = pd2; } else { cpu->Q1->processes = pd2; cpu->Q1->isEmpty = 0; } printQueues(out_file, cpu); } else { printf("PROCESS COMPLETED IN D2\n"); pd2->state = 0; Process* end_completed = get_end(completed); processCompleted++; pd2->completion_t = cpu->time; fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd2->id, pd2->waiting_cpu, pd2->waiting_io, (cpu->time - pd2->arrival_time)); if (end_completed != NULL) { end_completed->next = pd2; } else { completed->processes = pd2; completed->isEmpty = 0; } printQueues(out_file, cpu); } } } } if (pd3 != NULL) { //Handle running process in device 3 printf("PROCESS IN D3\n"); Burst* bd3 = get_next_incomplete_burst(pd3); if (bd3 != NULL) { printf("D3 PROCESS BURST EXISTS\n"); bd3->time_remaining--; if (bd3->time_remaining == 0) { printf("BURST IN D3 FINISHED\n"); bd3->completed = 1; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd3->id, bd3->device_num); cpu->D3->processes = pd3->next; if (cpu->D1->processes != NULL) { cpu->D3->processes->waiting_io++; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd3->next->id, bd3->device_num); } if (bd3->next_burst != NULL) { printf("MOVING PROCESS FROM D3 to Q1\n"); Process* end_q = get_end(cpu->Q1); fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd3->id); pd3->next = NULL; if (end_q != NULL) { end_q->next = pd3; } else { cpu->Q1->processes = pd3; cpu->Q1->isEmpty = 0; } printQueues(out_file, cpu); } else { printf("PROCESS COMPLETED IN D3\n"); pd3->state = 0; Process* end_completed = get_end(completed); processCompleted++; pd3->completion_t = cpu->time; fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd3->id, pd3->waiting_cpu, pd3->waiting_io, (cpu->time - pd3->arrival_time)); if (end_completed != NULL) { end_completed->next = pd3; } else { completed->processes = pd3; completed->isEmpty = 0; } printQueues(out_file, cpu); } } } } if (pd4 != NULL) {//Handle running process in device 4 printf("PROCESS IN D4\n"); Burst* bd4 = get_next_incomplete_burst(pd4); if (bd4 != NULL) { printf("D4 PROCESS BURST EXISTS\n"); bd4->time_remaining--; if (bd4->time_remaining == 0) { printf("BURST IN D4 FINISHED\n"); bd4->completed = 1; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd4->id, bd4->device_num); cpu->D4->processes = pd4->next; if (cpu->D1->processes != NULL) { cpu->D4->processes->waiting_io++; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd4->next->id, bd4->device_num); } if (bd4->next_burst != NULL) { printf("MOVING PROCESS FROM D4 to Q1\n"); Process* end_q = get_end(cpu->Q1); fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd4->id); pd4->next = NULL; if (end_q != NULL) { end_q->next = pd4; } else { cpu->Q1->processes = pd4; cpu->Q1->isEmpty = 0; } printQueues(out_file, cpu); } else { printf("PROCESS COMPLETED IN D4\n"); pd4->state = 0; Process* end_completed = get_end(completed); processCompleted++; pd4->completion_t = cpu->time; fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd4->id, pd4->waiting_cpu, pd4->waiting_io, (cpu->time - pd4->arrival_time)); if (end_completed != NULL) { end_completed->next = pd4; } else { completed->processes = pd4; completed->isEmpty = 0; } printQueues(out_file, cpu); } } } } if (pd5 != NULL) {//Handle running process in device 5 printf("PROCESS IN D5\n"); Burst* bd5 = get_next_incomplete_burst(pd5); if (bd5 != NULL) { printf("D5 PROCESS BURST EXISTS\n"); bd5->time_remaining--; if (bd5->time_remaining == 0) { printf("BURST IN D5 FINISHED\n"); bd5->completed = 1; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d completed on device %d\n", cpu->time, pd5->id, bd5->device_num); cpu->D5->processes = pd5->next; if (cpu->D1->processes != NULL) { cpu->D5->processes->waiting_io++; fprintf(out_file, "Time: %-5d\tI/O burst of Process#%d running on device %d\n", cpu->time, pd5->next->id, bd5->device_num); } if (bd5->next_burst != NULL) { printf("MOVING PROCESS FROM D5 to Q1\n"); Process* end_q = get_end(cpu->Q1); fprintf(out_file, "Time: %-5d\tMoving Process#%d to Q1\n", cpu->time, pd5->id); pd5->next = NULL; if (end_q != NULL) { end_q->next = pd5; } else { cpu->Q1->processes = pd5; cpu->Q1->isEmpty = 0; } printQueues(out_file, cpu); } else { printf("PROCESS COMPLETED IN D5\n"); pd5->state = 0; Process* end_completed = get_end(completed); processCompleted++; pd5->completion_t = cpu->time; fprintf(out_file, "Time: %-5d\tProcess#%d completed. Time waiting for CPU: %d Time waiting for I/O: %d Total completion time: %d\n", cpu->time, pd5->id, pd5->waiting_cpu, pd5->waiting_io, (cpu->time - pd5->arrival_time)); if (end_completed != NULL) { end_completed->next = pd5; } else { completed->processes = pd5; completed->isEmpty = 0; } printQueues(out_file, cpu); } } } } //Increment the io waiting time for all processes in device queues after the first process in each pd1 = cpu->D1->processes; pd2 = cpu->D2->processes; pd3 = cpu->D3->processes; pd4 = cpu->D4->processes; pd5 = cpu->D5->processes; if (pd1 != NULL) { //Handle device 1 pd1 = pd1->next; while (pd1 != NULL) { printf("Incrementing device 1 waiting\n"); pd1->waiting_io++; pd1 = pd1->next; } } if (pd2 != NULL) { //Handle device 2 pd2 = pd2->next; while (pd2 != NULL) { printf("Incrementing device 2 waiting\n"); pd2->waiting_io++; pd2 = pd2->next; } } if (pd3 != NULL) { //Handle device 3 pd3 = pd3->next; while (pd3 != NULL) { printf("Incrementing device 3 waiting\n"); pd3->waiting_io++; pd3 = pd3->next; } } if (pd4 != NULL) { //Handle device 4 pd4 = pd4->next; while (pd4 != NULL) { printf("Incrementing device 4 waiting\n"); pd4->waiting_io++; pd4 = pd4->next; } } if (pd5 != NULL) { //Handle device 5 pd5 = pd5->next; while (pd5 != NULL) { printf("Incrementing device 5 waiting\n"); pd5->waiting_io++; pd5 = pd5->next; } } //If cpu is running in Q3 //Check for other processes with shorter remaining times //If there is one move running process to end of Q3 //Check if Q1 and Q2 are empty, if either isnt free up the cpu and put the running process back into Q3 if (cpu->queue == 3 && cpu->current_process != NULL) { printf("CPU is in Q3\n"); if (cpu->Q1->processes != NULL || cpu->Q2->processes != NULL || shortest(cpu->current_process, cpu->Q3) == 0) { printf("PROCESS IN Q3 IS BEING PREEMTED\n"); Process* end_que = get_end(cpu->Q3); cpu->current_process->state = 2; fprintf(out_file, "Time: %-5d\tProcess#%d has been moved back into Q3 due to there being a shorter process in Q3 to run or there are processes in Q2 or Q1 that need to be run\n", cpu->time, cpu->current_process->id); if (end_que != NULL) { end_que->next = cpu->current_process; } else { cpu->Q3->processes = cpu->current_process; cpu->Q3->isEmpty = 0; } cpu->current_process = NULL; cpu->idle = 1; cpu->queue = 0; printQueues(out_file, cpu); } else { printf("NOTHING IN Q3 PREMTED\n"); } } //If cpu is running in Q2 //If the current process time on cpu > TQ2 //Move process to Q3 and set cpu to idle //If Q1 isnt empty move running process back into Q2, but dont reset its time on the cpu if (cpu->queue == 2) { printf("CPU is in Q2\n"); if (get_next_incomplete_burst(cpu->current_process) != NULL && get_next_incomplete_burst(cpu->current_process)->time_active > cpu->TQ2) { //Time ran out for the process move it to Q3 printf("TIME RAN OUT FOR PROCESS IN Q2\n"); fprintf(out_file, "Time: %-5d\tProcess#%d moved to Q3 for not being able to complete within the Time Quantum of Q2\n", cpu->time, cpu->current_process->id); Process* end_q3 = get_end(cpu->Q3); cpu->current_process->state = 2; if (end_q3 != NULL) { end_q3->next = cpu->current_process; } else { cpu->Q3->processes = cpu->current_process; cpu->Q3->isEmpty = 0; } cpu->current_process = NULL; cpu->idle = 1; cpu->queue = 0; printQueues(out_file, cpu); } else if (cpu->Q1->isEmpty == 0) { //Preempt the process since there are processes in Q1 printf("PREMETING PROCESS IN Q2 FOR ONE IN Q1\n"); fprintf(out_file, "Time: %-5d\tProcess#%d moved back into Q2 because there are processes in Q1 that need to be run\n", cpu->time, cpu->current_process->id); Process* end_q2 = get_end(cpu->Q2); cpu->current_process->state = 2; if (end_q2 != NULL) { end_q2->next = cpu->current_process; } else { cpu->Q2->processes = cpu->current_process; cpu->Q2->isEmpty = 0; } cpu->current_process = NULL; cpu->idle = 1; cpu->queue = 0; printQueues(out_file, cpu); } else { printf("NOTHING MOVED OFF CPU FROM Q2\n"); } } //If the cpu is running in Q1 //If the current process time on cpu > TQ1 //Move the process to Q2 and set cpu to idle if (cpu->queue == 1) { printf("CPU is in Q1\n"); if (get_next_incomplete_burst(cpu->current_process) != NULL && get_next_incomplete_burst(cpu->current_process)->time_active > cpu->TQ1) { //Time ran out for the process move it to Q2 printf("TIME RAN OUT FOR PROCESS IN Q1\n"); fprintf(out_file, "Time: %-5d\tProcess#%d moved to Q2 because it could not complete within the Time Quantum of Q1\n", cpu->time, cpu->current_process->id); Process* end_q2 = get_end(cpu->Q2); get_next_incomplete_burst(cpu->current_process)->time_active = 0; cpu->current_process->state = 2; if (end_q2 != NULL) { end_q2->next = cpu->current_process; } else { cpu->Q2->processes = cpu->current_process; cpu->Q2->isEmpty = 0; } cpu->current_process = NULL; cpu->idle = 1; cpu->queue = 0; printQueues(out_file, cpu); } else { printf("NOTHING REMOVED FOR TIME FROM Q1\n"); } } //If Q1 has stuff in it and the cpu is free //Put the first thing from Q1 onto the cpu if (cpu->Q1->processes != NULL && cpu->idle == 1) { printf("Q1 not empty and CPU idle\n"); Process* q1_popped = cpu->Q1->processes; fprintf(out_file, "Time: %-5d\tMoving Process#%d from Q1 onto the CPU\n", cpu->time, q1_popped->id); cpu->Q1->processes = q1_popped->next; q1_popped->next = NULL; if (cpu->Q1->processes == NULL) { cpu->Q1->isEmpty = 1; } cpu->current_process = q1_popped; cpu->queue = 1; cpu->idle = 0; q1_popped->state = 1; printQueues(out_file, cpu); }//Else If Q2 has stuff in it and the cpu is free //Put the first thing from Q2 onto the cpu else if (cpu->Q2->processes != NULL && cpu->idle == 1) { printf("Q2 not empty and CPU idle\n"); Process* q2_popped = cpu->Q2->processes; fprintf(out_file, "Time: %-5d\tMoving Process#%d from Q2 onto the CPU\n", cpu->time, q2_popped->id); cpu->Q2->processes = q2_popped->next; q2_popped->next = NULL; if (cpu->Q2->processes == NULL) { cpu->Q2->isEmpty = 1; } cpu->current_process = q2_popped; cpu->queue = 2; cpu->idle = 0; q2_popped->state = 1; printQueues(out_file, cpu); }//Else If Q3 has stuff in it and the cpu is free //Put the lowest time remaining onto the cpu else if (cpu->Q3->processes != NULL && cpu->idle == 1) { printf("Q3 not empty and CPU idle\n"); //FIX THIS //Process* shortest = get_shortest_remaining(cpu->Q3); Process* shortest = cpu->Q3->processes; cpu->Q3->processes = shortest->next; fprintf(out_file, "Time: %-5d\tMoving Process#%d from Q3 onto the CPU\n", cpu->time, shortest->id); cpu->current_process = shortest; cpu->queue = 3; cpu->idle = 0; shortest->state = 1; if (cpu->Q3->processes == NULL) { cpu->Q3->isEmpty = 1; } printQueues(out_file, cpu); } cpu->time++; printf("TIME: %d\n", cpu->time); } //Write final average data to the output file //Average waiting time //Average turnaround time int waiting_sum = 0; int total_sum = 0; Process* itr = completed->processes; while (itr != NULL) { waiting_sum += itr->waiting_cpu; total_sum += (itr->completion_t - itr->arrival_time); itr = itr->next; } fprintf(out_file, "\n\nAverage waiting time: %d\nAverage turnaround time: %d\n", waiting_sum / processCompleted, total_sum / processCompleted); fprintf(out_file, "\n\n############################################################\n"); fprintf(out_file, "Logging for Multi-Level Queue Scheduling Simulation Ended!\n"); fprintf(out_file, "############################################################\n"); fclose(out_file); } return (EXIT_SUCCESS); }
int main(int argc, char *argv[]) { char word[20]; //primul cuvant de pe fiecare linie din fisierul de intrare FILE *f = fopen(argv[1], "r"); int N; fscanf(f, "%d\n", &N); struct window *windows = new struct window[N]; //vector de ghisee Queue<person> *q = new Queue<person>[N]; //vector de cozii Stack<int> *s = new Stack<int>[N]; //vector de stive struct array arrayWindows; //retine cate ghisee au fost deschise si ID-urile arrayWindows.nrWindows = 0; arrayWindows.A = new int[N]; //citirea si interpretarea fisierului de input while(fscanf(f, "%s", word) == 1) { if(strcmp(word, "OPEN_WINDOW") == 0) { int window_id, weight_min, weight_max, q_, k; fscanf(f, "%d%d%d%d%d", &window_id, &weight_min, &weight_max, &q_, &k); open_window(windows, &arrayWindows, q, s, window_id, weight_min, weight_max, q_, k); } else if(strcmp(word, "ADD_PERSON") == 0) { int personal_id, package_weight, window_id; fscanf(f, "%d%d%d", &personal_id, &package_weight, &window_id); add_person(q, personal_id, package_weight, window_id); } else if(strcmp(word, "PROCESS") == 0) { int window_id, n_people; fscanf(f, "%d%d", &window_id, &n_people); process(windows, arrayWindows, q, s, window_id, n_people); } else if(strcmp(word, "PROCESS_ALL") == 0) { int window_id; fscanf(f, "%d", &window_id); processAll(windows, arrayWindows, q, s, window_id); } else if(strcmp(word, "PRINT_QUEUES") == 0) printQueues(q, arrayWindows); else if(strcmp(word, "PRINT_STACKS") == 0) printStacks(s, arrayWindows); else if(strcmp(word, "FLUSH_STACKS") == 0) flushStacks(s, arrayWindows); } fclose(f); return 0; }