#include #include #include #include #include #include #include #include using namespace std; struct process_detail { //cpu_burst_times[0] is arrival time int pid; vector burst_times; int in_cpu; int current_burst_index; }; struct clock{ int push_signal; //boolean int timer; }; vector processes; queue ready_queue_fifo; struct process_detail* CPU = NULL; vector waiting; ofstream output_file("cpu_times.txt"); // -------------------------------------- THE FIFO -------------------------------------------------- void fifo() { //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_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()) { CPU = ready_queue_fifo.front(); CPU->in_cpu = 1; // Record in_time when the process enters the CPU output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1 ) / 2<< " " << time.timer; ready_queue_fifo.pop(); } 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_fifo.empty()) { CPU = ready_queue_fifo.front(); // process added to CPU CPU->in_cpu = 1; output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; // New entry time ready_queue_fifo.pop(); } else { CPU = NULL; } } } } } 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++; } output_file.close(); 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 << "," << (CPU->current_burst_index + 1) / 2 << " " << 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 << "," << (CPU->current_burst_index + 1) / 2 << " " << 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 << "," << (CPU->current_burst_index + 1) / 2 << " " << 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 << "," << (CPU->current_burst_index + 1) / 2 << " " << 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 << "," << (CPU->current_burst_index + 1) / 2 << " " << 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 << "," << (CPU->current_burst_index + 1) / 2 << " " << 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 -------------------------------------------------- // vector waiting; void round_robin() { //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(); // memset(&waiting, 0, process_count); int completed_processes = 0; int time_quantum = 5; 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 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_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()) { CPU = ready_queue_fifo.front(); CPU->in_cpu = 1; // Record in_time when the process enters the CPU output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; ready_queue_fifo.pop(); current_quantum = time_quantum; } 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 || current_quantum == 0){ // Record out_time when the process exits the CPU output_file << " " << time.timer << endl; CPU->in_cpu = 0; if(CPU->burst_times[processes[i].current_burst_index] == 0) CPU->current_burst_index++; if(current_quantum == 0) ready_queue_fifo.push(CPU); 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; output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; // New entry time ready_queue_fifo.pop(); current_quantum = time_quantum; } else { CPU = NULL; } } } } } if(CPU != NULL) { CPU->burst_times[CPU->current_burst_index]--; current_quantum--; } 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++; } output_file.close(); return; } int main(int argc, char **argv) { if(argc != 3) { cout <<"usage: ./scheduler.out \nprovided arguments:\n"; for(int i = 0; i < argc; i++) cout << argv[i] << "\n"; return -1; } char *file_to_search_in = argv[1]; char *scheduler_algorithm = argv[2]; ifstream file(file_to_search_in, ios::binary); // ifstream file("process1.dat", ios::binary); string buffer; int pid = 0; while(getline(file, buffer)) { if(buffer[0] == '<'){ continue; } istringstream iss(buffer); string word; struct process_detail pd; memset(&pd,0,sizeof(struct process_detail)); pd.pid = pid++; pd.current_burst_index = 0; while(iss>>word){ pd.burst_times.push_back(stoi(word)); } processes.push_back(pd); } map temp; temp["fifo"] = 1; temp["sjf"] = 2; temp["pre_sjf"] = 3; temp["rr"] = 4; string temp1 = scheduler_algorithm; // string temp1 = "rr"; 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 or sjf or pre_sjf or rr" << endl; } return 0; }