#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_cpu1; int in_cpu2; int current_burst_index; }; struct clock{ int push_signal; //boolean int timer; }; vector processes; queue ready_queue_fifo; vector waiting; process_detail* CPU1 = NULL; process_detail* CPU2 = NULL; 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 = 5; int process_count = processes.size(); int completed_processes = 0; string out_string1 = ""; string out_string2 = ""; while(completed_processes < process_count) { // 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(processes[i].in_cpu1 != 1 || processes[i].in_cpu2 != 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 (CPU1 == NULL && !ready_queue_fifo.empty()) { // Assign the first process from the ready queue to the CPU CPU1 = ready_queue_fifo.front(); CPU1->in_cpu1 = 1; // Record in_time when the process enters the CPU out_string1 = "P" + to_string(CPU1->pid+1) + ",1 " + to_string(time.timer); // output_file << "P" << CPU1->pid + 1 << ",1 " << time.timer; ready_queue_fifo.pop(); } if (CPU2 == NULL && !ready_queue_fifo.empty()) { // Assign the first process from the ready queue to the CPU CPU2 = ready_queue_fifo.front(); CPU2->in_cpu2 = 1; // Record in_time when the process enters the CPU // output_file << endl; out_string2 = "P" + to_string(CPU2->pid+1) + ",2 " + to_string(time.timer); // output_file << "P" << CPU2->pid + 1 << ",2 " << time.timer; ready_queue_fifo.pop(); } // Check CPU1 if(CPU1 != NULL) { //check cpu_burst complete for(int i = 0; i < process_count; ++i) { if(processes[i].in_cpu1 == 1) { if(CPU1->burst_times[processes[i].current_burst_index] == 0){ // Record out_time when the process exits the CPU out_string1 += " " + to_string(time.timer); output_file << out_string1 << endl; // output_file << " " << time.timer << endl; CPU1->in_cpu1 = 0; CPU1->current_burst_index++; waiting.push_back(CPU1); // process added to waiting queue if(!ready_queue_fifo.empty()) { CPU1 = ready_queue_fifo.front(); // process added to CPU CPU1->in_cpu1 = 1; // output_file << "P" << CPU1->pid+1 << ",1" << " " << time.timer; // New entry time out_string1 = "P" + to_string(CPU1->pid+1) + ",1 " + to_string(time.timer); ready_queue_fifo.pop(); } else { CPU1 = NULL; } } } } } if(CPU2 != NULL) { //check cpu_burst complete for(int i = 0; i < process_count; ++i) { if(processes[i].in_cpu2 == 1) { if(CPU2->burst_times[processes[i].current_burst_index] == 0){ // Record out_time when the process exits the CPU out_string2 += " " + to_string(time.timer); output_file << out_string2 << endl; // output_file << " " << time.timer << endl; CPU2->in_cpu2 = 0; CPU2->current_burst_index++; waiting.push_back(CPU2); // process added to waiting queue if(!ready_queue_fifo.empty()) { CPU2 = ready_queue_fifo.front(); // process added to CPU CPU2->in_cpu2 = 1; out_string2 = "P" + to_string(CPU2->pid+1) + ",2 " + to_string(time.timer); // output_file << "P" << CPU2->pid+1 << ",2" << " " << time.timer; // New entry time ready_queue_fifo.pop(); } else { CPU2 = NULL; } } } } } if(CPU1 != NULL) { CPU1->burst_times[CPU1->current_burst_index]--; } if(CPU2 != NULL) { CPU2->burst_times[CPU2->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 } } } // Increment the timer time.timer++; } output_file.close(); return; } // ----------------------------------------THE Shortest Job First---------------------------------- // 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 = 5; int process_count = processes.size(); int completed_processes = 0; string out_string1 = ""; string out_string2 = ""; while(completed_processes < process_count) { // 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(processes[i].in_cpu1 != 1 || processes[i].in_cpu2 != 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 (CPU1 == NULL && !ready_queue.empty()) { // Assign the first process from the ready queue to the CPU CPU1 = ready_queue.top(); CPU1->in_cpu1 = 1; // Record in_time when the process enters the CPU out_string1 = "P" + to_string(CPU1->pid+1) + ",1 " + to_string(time.timer); // output_file << "P" << CPU1->pid + 1 << ",1 " << time.timer; ready_queue.pop(); } if (CPU2 == NULL && !ready_queue.empty()) { // Assign the first process from the ready queue to the CPU CPU2 = ready_queue.top(); CPU2->in_cpu2 = 1; // Record in_time when the process enters the CPU // output_file << endl; out_string2 = "P" + to_string(CPU2->pid+1) + ",2 " + to_string(time.timer); // output_file << "P" << CPU2->pid + 1 << ",2 " << time.timer; ready_queue.pop(); } // Check CPU1 if(CPU1 != NULL) { //check cpu_burst complete for(int i = 0; i < process_count; ++i) { if(processes[i].in_cpu1 == 1) { if(CPU1->burst_times[processes[i].current_burst_index] == 0){ // Record out_time when the process exits the CPU out_string1 += " " + to_string(time.timer); output_file << out_string1 << endl; // output_file << " " << time.timer << endl; CPU1->in_cpu1 = 0; CPU1->current_burst_index++; waiting.push_back(CPU1); // process added to waiting queue if(!ready_queue.empty()) { CPU1 = ready_queue.top(); // process added to CPU CPU1->in_cpu1 = 1; // output_file << "P" << CPU1->pid+1 << ",1" << " " << time.timer; // New entry time out_string1 = "P" + to_string(CPU1->pid+1) + ",1 " + to_string(time.timer); ready_queue.pop(); } else { CPU1 = NULL; } } } } } if(CPU2 != NULL) { //check cpu_burst complete for(int i = 0; i < process_count; ++i) { if(processes[i].in_cpu2 == 1) { if(CPU2->burst_times[processes[i].current_burst_index] == 0){ // Record out_time when the process exits the CPU out_string2 += " " + to_string(time.timer); output_file << out_string2 << endl; // output_file << " " << time.timer << endl; CPU2->in_cpu2 = 0; CPU2->current_burst_index++; waiting.push_back(CPU2); // process added to waiting queue if(!ready_queue.empty()) { CPU2 = ready_queue.top(); // process added to CPU CPU2->in_cpu2 = 1; out_string2 = "P" + to_string(CPU2->pid+1) + ",2 " + to_string(time.timer); // output_file << "P" << CPU2->pid+1 << ",2" << " " << time.timer; // New entry time ready_queue.pop(); } else { CPU2 = NULL; } } } } } if(CPU1 != NULL) { CPU1->burst_times[CPU1->current_burst_index]--; } if(CPU2 != NULL) { CPU2->burst_times[CPU2->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 } } } // Increment the timer 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("temp.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 = "fifo"; 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; }