From fc7925be3edcec073472d905b772eed9ebef1348 Mon Sep 17 00:00:00 2001 From: Jai Sharma Sharma <220120009@iitdh.ac.in> Date: Mon, 30 Sep 2024 23:50:29 +0530 Subject: [PATCH] sched done --- lab3/src/scheduler.cpp | 1184 ++++++++++++++++++++-------------------- 1 file changed, 596 insertions(+), 588 deletions(-) diff --git a/lab3/src/scheduler.cpp b/lab3/src/scheduler.cpp index 3645ece..7232ead 100644 --- a/lab3/src/scheduler.cpp +++ b/lab3/src/scheduler.cpp @@ -1,588 +1,596 @@ -#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; - int arrvival_time = 0; - int wait_time = 0; - int cpu_time = 0; - int completion_time = 0; -}; - -struct clock{ - int timer; -}; - -vector processes; -queue ready_queue_fifo; -struct process_detail* CPU = NULL; -ofstream output_file("cpu_times.txt"); -vector out_strings; - - -// -------------------------------------- THE FIFO -------------------------------------------------- - -void fifo() { - - //clock initialized to 0 - struct clock time; - memset(&time, 0, sizeof(struct clock)); - time.timer = 0; - int process_count = processes.size(); - int completed_processes = 0; - vector waiting(process_count, NULL); - string out_string = ""; - - 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 j = 0; j < process_count; ++j) { - if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { - waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; - waiting[j] = NULL; - 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]) { - processes[i].arrvival_time = time.timer; - 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 - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // 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) { - processes[i].cpu_time += 1; - if(CPU->burst_times[processes[i].current_burst_index] == 0){ - // Record out_time when the process exits the CPU - out_string += " " + to_string(time.timer); - out_strings.push_back(out_string); - // output_file << " " << time.timer << endl; - CPU->in_cpu = 0; - CPU->current_burst_index++; - waiting[CPU->pid] = CPU; // process added to waiting queue - if(!ready_queue_fifo.empty()) { - CPU = ready_queue_fifo.front(); // process added to CPU - CPU->in_cpu = 1; - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // 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++; - } - 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 - if (a->current_burst_index == 0) { - return a->burst_times[a->current_burst_index + 1] > b->burst_times[b->current_burst_index]; - } - else if(b->current_burst_index == 0) { - return a->burst_times[a->current_burst_index] > b->burst_times[b->current_burst_index+1]; - - } - else if(b->current_burst_index == 0 && a->current_burst_index == 0) - return a->burst_times[a->current_burst_index+1] > b->burst_times[b->current_burst_index+1]; - else 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; - int process_count = processes.size(); - int completed_processes = 0; - // Initialize waiting vector with NULLs for each process slot - vector waiting(process_count, NULL); - string out_string = ""; - - 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 j = 0; j < process_count; ++j) { - if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { - waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; - waiting[j] = NULL; - 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 < process_count; ++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 - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; - ready_queue.pop(); - } - - if(CPU != NULL){ - //check cpu_burst complete - for(int i = 0; i < process_count; ++i) { - if(processes[i].in_cpu == 1) { - processes[i].cpu_time += 1; - if(CPU->burst_times[processes[i].current_burst_index] == 0){ - // Record out_time when the process exits the CPU - out_string += " " + to_string(time.timer); - out_strings.push_back(out_string); - // output_file << " " << time.timer << endl; - CPU->in_cpu = 0; - CPU->current_burst_index++; - waiting[CPU->pid] = CPU; // process added to waiting queue - if(!ready_queue.empty()) { - CPU = ready_queue.top(); // process added to CPU - CPU->in_cpu = 1; - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // 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++; - } - return; -} - -// ------------------------------------Pre-emptive shortest job -------------------------------------------- - -void pre_sjf() { - - //clock initialized to 0 - struct clock time; - memset(&time, 0, sizeof(struct clock)); - time.timer = 0; - int process_count = processes.size(); - int completed_processes = 0; - // Initialize waiting vector with NULLs for each process slot - vector waiting(process_count, NULL); - string out_string = ""; - - 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 j = 0; j < process_count; ++j) { - if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { - waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; - waiting[j] = NULL; - 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; - out_string += " " + to_string(time.timer); - out_strings.push_back(out_string); - // output_file << " " << time.timer << endl; - CPU = ready_queue.top(); - CPU->in_cpu = 1; - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // 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 < process_count; ++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; - out_string += " " + to_string(time.timer); - out_strings.push_back(out_string); - // output_file << " " << time.timer << endl; - CPU = ready_queue.top(); - CPU->in_cpu = 1; - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // 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; // Process leaves waiting queue - } - } - } - - if(CPU == NULL && !ready_queue.empty()) { - CPU = ready_queue.top(); - CPU->in_cpu = 1; - // Record in_time when the process enters the CPU - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; - ready_queue.pop(); - } - - if(CPU != NULL){ - //check cpu_burst complete - for(int i = 0; i < process_count; ++i) { - if(processes[i].in_cpu == 1) { - processes[i].cpu_time += 1; - if(CPU->burst_times[processes[i].current_burst_index] == 0){ - // Record out_time when the process exits the CPU - out_string += " " + to_string(time.timer); - out_strings.push_back(out_string); - // output_file << " " << time.timer << endl; - CPU->in_cpu = 0; - CPU->current_burst_index++; - waiting[CPU->pid] = CPU; // process added to waiting queue - if(!ready_queue.empty()) { - CPU = ready_queue.top(); // process added to CPU - CPU->in_cpu = 1; - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // 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) waiting[j]->wait_time += 1; - 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++; - } - return; -} - - -// ------------------------------------------- Round Robin -------------------------------------------------- - -void round_robin() { - struct clock time; - memset(&time, 0, sizeof(struct clock)); - time.timer = 0; - int process_count = processes.size(); - int completed_processes = 0; - int time_quantum = 5; - int current_quantum = 0; - - // Initialize waiting vector with NULLs for each process slot - vector waiting(process_count, NULL); - string out_string = ""; - - while (completed_processes < process_count) { - // Check for process completion - for (int j = 0; j < process_count; ++j) { - if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { - waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; - waiting[j] = NULL; - completed_processes++; - } - } - - // Manage arrival times - for (int i = 0; i < process_count; ++i) { - if (processes[i].in_cpu != 1 && time.timer == processes[i].burst_times[0]) { - ready_queue_fifo.push(&processes[i]); - processes[i].current_burst_index++; - } - } - - // Manage waiting queue - for (int j = 0; j < process_count; ++j) { - if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { - ready_queue_fifo.push(waiting[j]); - waiting[j]->current_burst_index++; - waiting[j] = NULL; // Process leaves waiting queue - } - } - - // Assign a process to CPU if available - if (CPU == NULL && !ready_queue_fifo.empty()) { - CPU = ready_queue_fifo.front(); - CPU->in_cpu = 1; - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // output_file << "P" << CPU->pid + 1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; - ready_queue_fifo.pop(); - current_quantum = time_quantum; - } - - if (CPU != NULL) { - for(int i = 0; i < process_count; ++i) { - if(processes[i].in_cpu == 1){ - processes[i].cpu_time += 1; - if (CPU->burst_times[CPU->current_burst_index] == 0 || current_quantum == 0) { - // output_file << " " << time.timer << endl; - out_string += " " + to_string(time.timer); - out_strings.push_back(out_string); - CPU->in_cpu = 0; - if (CPU->burst_times[CPU->current_burst_index] == 0){ - CPU->current_burst_index++; - waiting[CPU->pid] = CPU; - } - - else if (current_quantum == 0) ready_queue_fifo.push(CPU); - - // Place the process in its corresponding waiting slot by pid - - if (!ready_queue_fifo.empty()) { - CPU = ready_queue_fifo.front(); - CPU->in_cpu = 1; - out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); - // output_file << "P" << CPU->pid + 1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; - ready_queue_fifo.pop(); - current_quantum = time_quantum; - } else { - CPU = NULL; - } - } - } - } - } - - // Process CPU burst and quantum - if (CPU != NULL) { - CPU->burst_times[CPU->current_burst_index]--; - current_quantum--; - } - - // Manage IO bursts in waiting queue - for (int j = 0; j < process_count; ++j) { - if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] != 0) { - waiting[j]->burst_times[waiting[j]->current_burst_index]--; - } - } - - // Increment the timer - time.timer++; - } - -} - - -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("../WorkloadFiles/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 = "sjf"; - - // Start time point - auto start = std::chrono::high_resolution_clock::now(); - - 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; - } - - // End time point - auto end = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(end - start); - - - for(int i = 0; i < out_strings.size(); ++i){ - output_file << out_strings[i] << endl; - } - output_file.close(); - for(int i = 0; i < processes.size(); ++i) { - cout << "Process " << i+1 << " Completion Time: " << processes[i].completion_time << endl; - } - for(int i = 0; i < processes.size(); ++i) { - cout << "Process " << i+1 << " Waiting Time: " << processes[i].completion_time - processes[i].cpu_time << endl; - // cout << "Process " << i+1 << " Waiting Time: " << processes[i].wait_time << endl; - } - - std::cout << "Execution time: " << duration.count() << " ms" << std::endl; - return 0; -} +#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; + int arrvival_time = 0; + int wait_time = 0; + int cpu_time = 0; + int completion_time = 0; +}; + +struct clock{ + int timer; +}; + +vector processes; +queue ready_queue_fifo; +struct process_detail* CPU = NULL; +ofstream output_file("cpu_times.txt"); +vector out_strings; + + +// -------------------------------------- THE FIFO -------------------------------------------------- + +void fifo() { + + //clock initialized to 0 + struct clock time; + memset(&time, 0, sizeof(struct clock)); + time.timer = 0; + int process_count = processes.size(); + int completed_processes = 0; + vector waiting(process_count, NULL); + string out_string = ""; + + 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 j = 0; j < process_count; ++j) { + if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { + waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; + waiting[j] = NULL; + 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]) { + processes[i].arrvival_time = time.timer; + 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 + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // 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) { + processes[i].cpu_time += 1; + if(CPU->burst_times[processes[i].current_burst_index] == 0){ + // Record out_time when the process exits the CPU + out_string += " " + to_string(time.timer); + out_strings.push_back(out_string); + // output_file << " " << time.timer << endl; + CPU->in_cpu = 0; + CPU->current_burst_index++; + waiting[CPU->pid] = CPU; // process added to waiting queue + if(!ready_queue_fifo.empty()) { + CPU = ready_queue_fifo.front(); // process added to CPU + CPU->in_cpu = 1; + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // 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++; + } + 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 + if (a->current_burst_index == 0) { + return a->burst_times[a->current_burst_index + 1] > b->burst_times[b->current_burst_index]; + } + else if(b->current_burst_index == 0) { + return a->burst_times[a->current_burst_index] > b->burst_times[b->current_burst_index+1]; + + } + else if(b->current_burst_index == 0 && a->current_burst_index == 0) + return a->burst_times[a->current_burst_index+1] > b->burst_times[b->current_burst_index+1]; + else 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; + int process_count = processes.size(); + int completed_processes = 0; + // Initialize waiting vector with NULLs for each process slot + vector waiting(process_count, NULL); + string out_string = ""; + + 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 j = 0; j < process_count; ++j) { + if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { + waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; + waiting[j] = NULL; + 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 < process_count; ++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 + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; + ready_queue.pop(); + } + + if(CPU != NULL){ + //check cpu_burst complete + for(int i = 0; i < process_count; ++i) { + if(processes[i].in_cpu == 1) { + processes[i].cpu_time += 1; + if(CPU->burst_times[processes[i].current_burst_index] == 0){ + // Record out_time when the process exits the CPU + out_string += " " + to_string(time.timer); + out_strings.push_back(out_string); + // output_file << " " << time.timer << endl; + CPU->in_cpu = 0; + CPU->current_burst_index++; + waiting[CPU->pid] = CPU; // process added to waiting queue + if(!ready_queue.empty()) { + CPU = ready_queue.top(); // process added to CPU + CPU->in_cpu = 1; + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // 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++; + } + return; +} + +// ------------------------------------Pre-emptive shortest job -------------------------------------------- + +void pre_sjf() { + + //clock initialized to 0 + struct clock time; + memset(&time, 0, sizeof(struct clock)); + time.timer = 0; + int process_count = processes.size(); + int completed_processes = 0; + // Initialize waiting vector with NULLs for each process slot + vector waiting(process_count, NULL); + string out_string = ""; + + 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 j = 0; j < process_count; ++j) { + if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { + waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; + waiting[j] = NULL; + 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 && CPU->burst_times[CPU->current_burst_index] != 0) { + ready_queue.push(CPU); + CPU->in_cpu = 0; + out_string += " " + to_string(time.timer); + out_strings.push_back(out_string); + CPU = NULL; + // output_file << " " << time.timer << endl; + // CPU = ready_queue.top(); + // CPU->in_cpu = 1; + // out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // // output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; // New entry time + // ready_queue.pop(); + + } + else if(CPU != NULL && CPU->burst_times[CPU->current_burst_index] == 0) { + waiting[CPU->pid] = CPU; // because times up!! + CPU->in_cpu = 0; + CPU->current_burst_index++; + CPU = NULL; + + } + processes[i].current_burst_index++; + } + } + } + + // managing waiting queue + for(int j = 0; j < process_count; ++j) { + if(waiting[j] != NULL) { + if(waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { + ready_queue.push(waiting[j]); + // if(CPU != NULL && CPU->burst_times[processes[j].current_burst_index] != 0) { + // ready_queue.push(CPU); + // CPU->in_cpu = 0; + // out_string += " " + to_string(time.timer); + // out_strings.push_back(out_string); + // // output_file << " " << time.timer << endl; + // CPU = ready_queue.top(); + // CPU->in_cpu = 1; + // out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // // 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; // Process leaves waiting queue + } + } + } + + if(CPU == NULL && !ready_queue.empty()) { + CPU = ready_queue.top(); + CPU->in_cpu = 1; + // Record in_time when the process enters the CPU + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // output_file << "P" << CPU->pid+1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; + ready_queue.pop(); + } + + if(CPU != NULL){ + //check cpu_burst complete + for(int i = 0; i < process_count; ++i) { + if(processes[i].in_cpu == 1) { + processes[i].cpu_time += 1; + if(CPU->burst_times[processes[i].current_burst_index] == 0){ + // Record out_time when the process exits the CPU + out_string += " " + to_string(time.timer); + out_strings.push_back(out_string); + // output_file << " " << time.timer << endl; + CPU->in_cpu = 0; + CPU->current_burst_index++; + waiting[CPU->pid] = CPU; // process added to waiting queue + if(!ready_queue.empty()) { + CPU = ready_queue.top(); // process added to CPU + CPU->in_cpu = 1; + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // 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) waiting[j]->wait_time += 1; + 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++; + } + return; +} + + +// ------------------------------------------- Round Robin -------------------------------------------------- + +void round_robin() { + struct clock time; + memset(&time, 0, sizeof(struct clock)); + time.timer = 0; + int process_count = processes.size(); + int completed_processes = 0; + int time_quantum = 5; + int current_quantum = 0; + + // Initialize waiting vector with NULLs for each process slot + vector waiting(process_count, NULL); + string out_string = ""; + + while (completed_processes < process_count) { + // Check for process completion + for (int j = 0; j < process_count; ++j) { + if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == -2) { + waiting[j]->completion_time = time.timer - waiting[j]->arrvival_time - 1; + waiting[j] = NULL; + completed_processes++; + } + } + + // Manage arrival times + for (int i = 0; i < process_count; ++i) { + if (processes[i].in_cpu != 1 && time.timer == processes[i].burst_times[0]) { + ready_queue_fifo.push(&processes[i]); + processes[i].current_burst_index++; + } + } + + // Manage waiting queue + for (int j = 0; j < process_count; ++j) { + if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] == 0) { + ready_queue_fifo.push(waiting[j]); + waiting[j]->current_burst_index++; + waiting[j] = NULL; // Process leaves waiting queue + } + } + + // Assign a process to CPU if available + if (CPU == NULL && !ready_queue_fifo.empty()) { + CPU = ready_queue_fifo.front(); + CPU->in_cpu = 1; + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // output_file << "P" << CPU->pid + 1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; + ready_queue_fifo.pop(); + current_quantum = time_quantum; + } + + if (CPU != NULL) { + for(int i = 0; i < process_count; ++i) { + if(processes[i].in_cpu == 1){ + processes[i].cpu_time += 1; + if (CPU->burst_times[CPU->current_burst_index] == 0 || current_quantum == 0) { + // output_file << " " << time.timer << endl; + out_string += " " + to_string(time.timer); + out_strings.push_back(out_string); + CPU->in_cpu = 0; + if (CPU->burst_times[CPU->current_burst_index] == 0){ + CPU->current_burst_index++; + waiting[CPU->pid] = CPU; + } + + else if (current_quantum == 0) ready_queue_fifo.push(CPU); + + // Place the process in its corresponding waiting slot by pid + + if (!ready_queue_fifo.empty()) { + CPU = ready_queue_fifo.front(); + CPU->in_cpu = 1; + out_string = "P" + to_string(CPU->pid+1) + "," + to_string((CPU->current_burst_index + 1 ) / 2) + " " + to_string(time.timer); + // output_file << "P" << CPU->pid + 1 << "," << (CPU->current_burst_index + 1) / 2 << " " << time.timer; + ready_queue_fifo.pop(); + current_quantum = time_quantum; + } else { + CPU = NULL; + } + } + } + } + } + + // Process CPU burst and quantum + if (CPU != NULL) { + CPU->burst_times[CPU->current_burst_index]--; + current_quantum--; + } + + // Manage IO bursts in waiting queue + for (int j = 0; j < process_count; ++j) { + if (waiting[j] != NULL && waiting[j]->burst_times[waiting[j]->current_burst_index] != 0) { + waiting[j]->burst_times[waiting[j]->current_burst_index]--; + } + } + + // Increment the timer + time.timer++; + } + +} + + +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("../WorkloadFiles/process2.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 = "pre_sjf"; + + // Start time point + auto start = std::chrono::high_resolution_clock::now(); + + 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; + } + + // End time point + auto end = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + + + for(int i = 0; i < out_strings.size(); ++i){ + output_file << out_strings[i] << endl; + } + output_file.close(); + for(int i = 0; i < processes.size(); ++i) { + cout << "Process " << i+1 << " Completion Time: " << processes[i].completion_time << endl; + } + for(int i = 0; i < processes.size(); ++i) { + cout << "Process " << i+1 << " Waiting Time: " << processes[i].completion_time - processes[i].cpu_time << endl; + // cout << "Process " << i+1 << " Waiting Time: " << processes[i].wait_time << endl; + } + + std::cout << "Execution time: " << duration.count() << " ms" << std::endl; + return 0; +}