/* * 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); }
//---------------------------------------------- <CPU> //Agrega un nuevo cpu a la lista general de control void nucleo_nuevo_cpu(int cpu_socket){ t_CPU* cpu = new_cpu(cpu_socket); add_new_cpu(cpu); log_trace(nucleo_logger, "COMUNICACION: nuevo cpu conectado %d", cpu_socket); }
static void handle_one_cpu(unsigned int number, char *vendor, int family, int model) { char filename[1024]; ifstream file; unsigned int package_number = 0; unsigned int core_number = 0; class abstract_cpu *package, *core, *cpu; sprintf(filename, "/sys/devices/system/cpu/cpu%i/topology/core_id", number); file.open(filename, ios::in); if (file) { file >> core_number; file.close(); } sprintf(filename, "/sys/devices/system/cpu/cpu%i/topology/physical_package_id", number); file.open(filename, ios::in); if (file) { file >> package_number; if (package_number == (unsigned int) -1) package_number = 0; file.close(); } if (system_level.children.size() <= package_number) system_level.children.resize(package_number + 1, NULL); if (!system_level.children[package_number]) { system_level.children[package_number] = new_package(package_number, number, vendor, family, model); system_level.childcount++; } package = system_level.children[package_number]; package->parent = &system_level; if (package->children.size() <= core_number) package->children.resize(core_number + 1, NULL); if (!package->children[core_number]) { package->children[core_number] = new_core(core_number, number, vendor, family, model); package->childcount++; } core = package->children[core_number]; core->parent = package; if (core->children.size() <= number) core->children.resize(number + 1, NULL); if (!core->children[number]) { core->children[number] = new_cpu(number, vendor, family, model); core->childcount++; } cpu = core->children[number]; cpu->parent = core; if (number >= all_cpus.size()) all_cpus.resize(number + 1, NULL); all_cpus[number] = cpu; }
int main(int argc, char **argv) { int datasize = 10; int debug = 0; int usestdin = 0; int o; extern int optind; while ((o = getopt(argc, argv, "ds")) != -1) { switch (o) { case 'd': debug = 1; break; case 's': usestdin = 1; break; default: usage(argv[0]); exit(EXIT_SUCCESS); } } if (optind >= argc) { usage(argv[0]); exit(EXIT_SUCCESS); } char *input = argv[optind]; FILE *f; struct stat st; if ((f = fopen(input, "rb")) == NULL) { perror(argv[0]); exit(EXIT_FAILURE); } if (fstat(fileno(f), &st) < 0) { perror(argv[0]); exit(EXIT_FAILURE); } uint8_t *code; if ((code = malloc(st.st_size)) == NULL) { perror(argv[0]); exit(EXIT_FAILURE); } if ((fread(code, 1, st.st_size, f)) != st.st_size) { fprintf(stderr, "%s: error reading input file\n", argv[0]); exit(EXIT_FAILURE); } fclose(f); struct cpu *cpu = new_cpu(datasize); if (cpu == NULL) { fprintf(stderr, "error: can't create CPU\n"); exit(EXIT_FAILURE); } cpu->debug = debug; cpu->exception = exception; if (usestdin) { cpu->inbox = stdinbox; } else { cpu->inbox = inbox; } cpu->outbox = outbox; if (load_code(cpu, code, st.st_size) < 0) { fprintf(stderr, "error: can't load code\n"); exit(EXIT_FAILURE); } free(code); cpu->data[9] = 0; run_cpu(cpu); printf("Executed %d instructions\n", cpu->clock); exit(EXIT_SUCCESS); }