diff --git a/lab3/scheduler.cpp b/lab3/scheduler.cpp index 7e9ae68..c4aa50c 100644 --- a/lab3/scheduler.cpp +++ b/lab3/scheduler.cpp @@ -23,24 +23,15 @@ struct clock{ }; -//// operator overloading -//struct CompareHeight { -// bool operator()(struct process_detail p1, struct process_detail p2) -// { -// // return "true" if "p1" is ordered -// // before "p2", for example: -// return p1.height < p2.height; -// } -//}; - - vector processes; queue ready_queue_fifo; -vector waiting; struct process_detail* CPU = NULL; +vector waiting; ofstream output_file("cpu_times.txt"); +// -------------------------------------- THE FIFO -------------------------------------------------- + void fifo() { //clock initialized to 0 @@ -53,9 +44,11 @@ void fifo() { while(completed_processes < process_count){ + // ready queue, waiting queue, cpu in check, ready queue subtraction, waiting queue subtraction + // breaking from the infinite loop for(int i = 0; i < process_count; ++i) { - if(processes[i].burst_times[processes[i].current_burst_index] == -1) { + if(processes[i].burst_times[processes[i].current_burst_index] == -2) { completed_processes++; } } @@ -70,80 +63,411 @@ void fifo() { } } } + + // managing waiting queue + for(int j = 0; j < waiting.size(); ++j) { + if(waiting[j] != NULL) { + if(waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { + ready_queue_fifo.push(waiting[j]); + waiting[j]->current_burst_index++; + waiting[j] = NULL; + } + } + } - //THE FIFO RULE if(CPU == NULL && !ready_queue_fifo.empty()) { CPU = ready_queue_fifo.front(); CPU->in_cpu = 1; // Record in_time when the process enters the CPU - CPU->burst_times[CPU->current_burst_index]--; - output_file << "P" << CPU->pid+1 << " " << time.timer; + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; ready_queue_fifo.pop(); } - // else if(CPU == NULL && ready_queue_fifo.empty()) { - // // removing form waiting list - // for(int j = 0; j < waiting.size(); ++j) { - // if(waiting[j] != NULL) { - // if(waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { - // ready_queue_fifo.push(waiting[j]); - // waiting[j]->current_burst_index++; - // waiting[j] = NULL; - // } - // else waiting[j]->burst_times[waiting[j]->current_burst_index]--; // reducing the io burst till it reaches 0 - // } - // } - // time.push_signal++; - // } - else { - // removing form waiting list - for(int j = 0; j < waiting.size(); ++j) { - if(waiting[j] != NULL) { - if(waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { - ready_queue_fifo.push(waiting[j]); - waiting[j]->current_burst_index++; - waiting[j] = NULL; - } - else waiting[j]->burst_times[waiting[j]->current_burst_index]--; // reducing the io burst till it reaches 0 - } - - } + else if(CPU != NULL){ //check cpu_burst complete for(int i = 0; i < process_count; ++i) { - if(processes[i].in_cpu == 1 && CPU != NULL) { + if(processes[i].in_cpu == 1) { if(CPU->burst_times[processes[i].current_burst_index] == 0){ // Record out_time when the process exits the CPU output_file << " " << time.timer << endl; - // time.push_signal = time.push_signal + CPU->burst_times[processes[i].current_burst_index] ; CPU->in_cpu = 0; CPU->current_burst_index++; - // CPU->burst_times[CPU->current_burst_index]--; waiting.push_back(CPU); // process added to waiting queue if(!ready_queue_fifo.empty()) { CPU = ready_queue_fifo.front(); // process added to CPU CPU->in_cpu = 1; - // CPU->burst_times[CPU->current_burst_index]--; - output_file << "P" << CPU->pid+1 << " " << time.timer; // New entry time + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; // New entry time ready_queue_fifo.pop(); } else { CPU = NULL; } } - else CPU->burst_times[CPU->current_burst_index]--; } } - } + + + if(CPU != NULL) { + CPU->burst_times[CPU->current_burst_index]--; + } + + for(int j = 0; j < waiting.size(); ++j) { + if(waiting[j] != NULL) { + if(waiting[j]->burst_times[waiting[j]->current_burst_index] != 0) { + waiting[j]->burst_times[waiting[j]->current_burst_index]--; // reducing the io burst till it reaches 0 + } + } + } + time.timer++; - // completed_processes++; } output_file.close(); - cout << "fifo" << endl; return; } + + +// ----------------------------------------- The Shortest Job Fist ------------------------------------------- +// Custom comparator for the priority queue +struct Compare { + bool operator()(process_detail* a, process_detail* b) { + // Compare the elements in the vector at the given indices + return a->burst_times[a->current_burst_index] > b->burst_times[b->current_burst_index]; + } +}; + +priority_queue, Compare> ready_queue; + +void sjf() { + + //clock initialized to 0 + struct clock time; + memset(&time, 0, sizeof(struct clock)); + time.timer = 0; + time.push_signal = 0; + int process_count = processes.size(); + int completed_processes = 0; + + while(completed_processes < process_count){ + + // ready queue, waiting queue, cpu in check, ready queue subtraction, waiting queue subtraction + + // breaking from the infinite loop + for(int i = 0; i < process_count; ++i) { + if(processes[i].burst_times[processes[i].current_burst_index] == -2) { + completed_processes++; + } + } + + //managing arrival times + for(int i = 0; i < process_count; ++i) { + //if process not in cpu + if(processes[i].in_cpu != 1) { + if(time.timer == processes[i].burst_times[0]) { + ready_queue.push(&processes[i]); + processes[i].current_burst_index++; + } + } + } + + // managing waiting queue + for(int j = 0; j < waiting.size(); ++j) { + if(waiting[j] != NULL) { + if(waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { + ready_queue.push(waiting[j]); + waiting[j]->current_burst_index++; + waiting[j] = NULL; + } + } + } + + if(CPU == NULL && !ready_queue.empty()) { + CPU = ready_queue.top(); + CPU->in_cpu = 1; + // Record in_time when the process enters the CPU + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; + ready_queue.pop(); + } + + else if(CPU != NULL){ + //check cpu_burst complete + for(int i = 0; i < process_count; ++i) { + if(processes[i].in_cpu == 1) { + if(CPU->burst_times[processes[i].current_burst_index] == 0){ + // Record out_time when the process exits the CPU + output_file << " " << time.timer << endl; + CPU->in_cpu = 0; + CPU->current_burst_index++; + waiting.push_back(CPU); // process added to waiting queue + if(!ready_queue.empty()) { + CPU = ready_queue.top(); // process added to CPU + CPU->in_cpu = 1; + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; // New entry time + ready_queue.pop(); + } + else { + CPU = NULL; + } + } + } + } + } + + + if(CPU != NULL) { + // reducing the cpu burst till it reaches 0 + CPU->burst_times[CPU->current_burst_index]--; + } + + for(int j = 0; j < waiting.size(); ++j) { + if(waiting[j] != NULL) { + if(waiting[j]->burst_times[waiting[j]->current_burst_index] != 0) { + // reducing the io burst till it reaches 0 + waiting[j]->burst_times[waiting[j]->current_burst_index]--; + } + } + } + + time.timer++; + } + output_file.close(); + return; +} + +// ------------------------------------Pre-emptive shortest job -------------------------------------------- + +void pre_sjf() { + + //clock initialized to 0 + struct clock time; + memset(&time, 0, sizeof(struct clock)); + time.timer = 0; + time.push_signal = 0; + int process_count = processes.size(); + int completed_processes = 0; + + while(completed_processes < process_count){ + + // ready queue, waiting queue, cpu in check, ready queue subtraction, waiting queue subtraction + + // breaking from the infinite loop + for(int i = 0; i < process_count; ++i) { + if(processes[i].burst_times[processes[i].current_burst_index] == -2) { + completed_processes++; + } + } + + //managing arrival times + for(int i = 0; i < process_count; ++i) { + //if process not in cpu + if(processes[i].in_cpu != 1) { + if(time.timer == processes[i].burst_times[0]) { + ready_queue.push(&processes[i]); + if(CPU != NULL) { + ready_queue.push(CPU); + CPU->in_cpu = 0; + output_file << " " << time.timer << endl; + CPU = ready_queue.top(); + CPU->in_cpu = 1; + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; // New entry time + ready_queue.pop(); + + } + processes[i].current_burst_index++; + } + } + } + + // managing waiting queue + for(int j = 0; j < waiting.size(); ++j) { + if(waiting[j] != NULL) { + if(waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { + ready_queue.push(waiting[j]); + if(CPU != NULL) { + ready_queue.push(CPU); + CPU->in_cpu = 0; + output_file << " " << time.timer << endl; + CPU = ready_queue.top(); + CPU->in_cpu = 1; + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; // New entry time + ready_queue.pop(); + + } + waiting[j]->current_burst_index++; + waiting[j] = NULL; + } + } + } + + if(CPU == NULL && !ready_queue.empty()) { + CPU = ready_queue.top(); + CPU->in_cpu = 1; + // Record in_time when the process enters the CPU + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; + ready_queue.pop(); + } + + else if(CPU != NULL){ + //check cpu_burst complete + for(int i = 0; i < process_count; ++i) { + if(processes[i].in_cpu == 1) { + if(CPU->burst_times[processes[i].current_burst_index] == 0){ + // Record out_time when the process exits the CPU + output_file << " " << time.timer << endl; + CPU->in_cpu = 0; + CPU->current_burst_index++; + waiting.push_back(CPU); // process added to waiting queue + if(!ready_queue.empty()) { + CPU = ready_queue.top(); // process added to CPU + CPU->in_cpu = 1; + output_file << "P" << CPU->pid+1 << ",1" << " " << time.timer; // New entry time + ready_queue.pop(); + } + else { + CPU = NULL; + } + } + } + } + } + + + if(CPU != NULL) { + // reducing the cpu burst till it reaches 0 + CPU->burst_times[CPU->current_burst_index]--; + } + + for(int j = 0; j < waiting.size(); ++j) { + if(waiting[j] != NULL) { + if(waiting[j]->burst_times[waiting[j]->current_burst_index] != 0) { + // reducing the io burst till it reaches 0 + waiting[j]->burst_times[waiting[j]->current_burst_index]--; + } + } + } + + time.timer++; + } + output_file.close(); + return; +} + + +// ------------------------------------------- Round Robin -------------------------------------------------- + +void round_robin() { + + // Clock initialized to 0 + struct clock time; + memset(&time, 0, sizeof(struct clock)); + time.timer = 0; + time.push_signal = 5; + int process_count = processes.size(); + int completed_processes = 0; + int time_quantum = 2; // Define a time quantum for Round Robin + + // To keep track of the remaining quantum for the current process + int current_quantum = 0; + + while (completed_processes < process_count) { + // Ready queue, waiting queue, CPU in check, ready queue subtraction, waiting queue subtraction + + // Breaking from the loop + for (int i = 0; i < process_count; ++i) { + if (processes[i].burst_times[processes[i].current_burst_index] == -2) { + completed_processes++; + } + } + + // Managing arrival times + for (int i = 0; i < process_count; ++i) { + // If process not in CPU + if (processes[i].in_cpu != 1) { + if (time.timer == processes[i].burst_times[0]) { + ready_queue_fifo.push(&processes[i]); + processes[i].current_burst_index++; + } + } + } + + // Managing waiting queue + for (int j = 0; j < waiting.size(); ++j) { + if (waiting[j] != NULL) { + if (waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { + ready_queue_fifo.push(waiting[j]); + waiting[j]->current_burst_index++; + waiting[j] = NULL; + } + } + } + + if (CPU == NULL && !ready_queue_fifo.empty()) { + // Assign the first process from the ready queue to the CPU + CPU = ready_queue_fifo.front(); + CPU->in_cpu = 1; + // Record in_time when the process enters the CPU + output_file << "P" << CPU->pid + 1 << ",1 " << time.timer; + ready_queue_fifo.pop(); + current_quantum = time_quantum; // Reset the time quantum for the new process + } + else if (CPU != NULL) { + // Check if CPU burst is complete or quantum expired + if (CPU->burst_times[CPU->current_burst_index] == 0 || current_quantum == 0) { + // Record out_time when the process exits the CPU + output_file << " " << time.timer << endl; + CPU->in_cpu = 0; + CPU->current_burst_index++; + + // If the process still has bursts left, move it to the waiting queue + if (CPU->burst_times[CPU->current_burst_index] > 0) { + waiting.push_back(CPU); + } + + // Assign the next process from the ready queue to the CPU + if (!ready_queue_fifo.empty()) { + CPU = ready_queue_fifo.front(); + CPU->in_cpu = 1; + output_file << "P" << CPU->pid + 1 << ",1 " << time.timer; // New entry time + ready_queue_fifo.pop(); + current_quantum = time_quantum; // Reset the time quantum for the new process + } + else { + CPU = NULL; + } + } + } + + if (CPU != NULL) { + // Decrement the burst time of the process currently in the CPU + CPU->burst_times[CPU->current_burst_index]--; + current_quantum--; // Decrement the quantum counter + // If quantum is exhausted but burst isn't finished, preempt the process + if (current_quantum == 0 && CPU->burst_times[CPU->current_burst_index] > 0) { + ready_queue_fifo.push(CPU); // Re-add the process to the ready queue + CPU->in_cpu = 0; + CPU = NULL; // Preempt the process from the CPU + } + } + + // Reduce the IO burst times of the processes in the waiting queue + for (int j = 0; j < waiting.size(); ++j) { + if (waiting[j] != NULL) { + if (waiting[j]->burst_times[waiting[j]->current_burst_index] != 0) { + waiting[j]->burst_times[waiting[j]->current_burst_index]--; // Reducing the IO burst until it reaches 0 + } + } + } + + time.timer++; + } + + output_file.close(); + return; + +} + int main(int argc, char **argv) { if(argc != 3) @@ -158,7 +482,6 @@ int main(int argc, char **argv) { char *scheduler_algorithm = argv[2]; ifstream file(file_to_search_in, ios::binary); - // ifstream file("process1.dat", ios::binary); string buffer; int pid = 0; @@ -174,44 +497,35 @@ int main(int argc, char **argv) { pd.current_burst_index = 0; while(iss>>word){ -// if(i == 0){ -// pd.cpu_burst_times.push_back(stoi(word)); -// } -// else if(i % 2 == 0){ -// pd.io_burst_times.push_back(stoi(word)); -// } -// else if(i % 2 == 1){ -// } pd.burst_times.push_back(stoi(word)); -// i++; -// cout << stoi(word) << endl; } processes.push_back(pd); } map temp; temp["fifo"] = 1; - string temp1 = scheduler_algorithm; - // string temp1 = "fifo"; + temp["sjf"] = 2; + temp["pre_sjf"] = 3; + temp["rr"] = 4; + string temp1 = scheduler_algorithm; switch(temp[temp1]){ case 1: fifo(); break; + case 2: + sjf(); + break; + case 3: + pre_sjf(); + break; + case 4: + round_robin(); + break; default: - cout << "enter fifo" << endl; + cout << "enter fifo or sjf or pre_sjf or rr" << endl; } - // cout << processes[0].in_cpu << endl; - // cout << processes[0].current_burst_index << endl; - - // cout << processes[1].in_cpu << endl; - // cout << processes[1].current_burst_index << endl; - - // cout << ready_queue_fifo.front()->pid << endl; - // ready_queue_fifo.pop(); - // cout << ready_queue_fifo.front()->pid << endl; - return 0; }