diff --git a/lab3/multi_core_scheduler.cpp b/lab3/multi_core_scheduler.cpp new file mode 100644 index 0000000..104303c --- /dev/null +++ b/lab3/multi_core_scheduler.cpp @@ -0,0 +1,390 @@ +#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; +} \ No newline at end of file diff --git a/lab3/prompt b/lab3/prompt deleted file mode 100644 index 2c23570..0000000 --- a/lab3/prompt +++ /dev/null @@ -1,225 +0,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 ptr; -}; - -struct clock{ - int push_signal; //boolean - int timer; - -}; - -//// 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; -vector ready_queue; -queue ready_queue_fifo; -vector waiting; -struct process_detail* CPU = NULL; - -void fifo() { - - //clock initialized to 0 - struct clock time; - memset(&time, 0, sizeof(struct clock)); - int process_count = processes.size(); - - //ready queue initialized as process 1 will arrive at time 0 - ready_queue_fifo.push(&processes[0]); - processes[0].ptr++; - - int brk = 0; - - while(true){ - for(int i = 0; i < process_count; ++i) { - if(processes[i].burst_times[processes[i].ptr] == -1) { - brk = 1; - } - else brk = 0; - } - if(brk) break; - - //managing arrival times - for(int i = 1; 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].ptr++; - } - } - } - - //THE FIFO RULE - if(CPU == NULL) { - CPU = ready_queue_fifo.front(); - CPU->in_cpu = 1; - ready_queue_fifo.pop(); - } - else { - //check cpu_burst complete - for(int i = 0; i < process_count; ++i) { - if(processes[i].in_cpu == 1) { - if(time.push_signal + CPU->burst_times[processes[i].ptr] == time.timer){ - waiting.push_back(CPU); // process added to waiting queue - CPU->in_cpu = 0; - CPU = ready_queue_fifo.front(); // process added to CPU - CPU->in_cpu = 1; - ready_queue_fifo.pop(); - time.push_signal = time.push_signal + CPU->burst_times[processes[i].ptr] ; - } - } - } - - // removing form waiting list - - for(int j = 0; j < waiting.size(); ++j) { - if(waiting[j] != NULL) { - if(waiting[j]->burst_times[waiting[j]->ptr] == 0) { - ready_queue_fifo.push(waiting[j]); - waiting[j]->ptr++; - waiting[j] = NULL; - } - else waiting[j]->burst_times[waiting[j]->ptr]--; // reducing the io burst till it reaches 0 - } - - } - } - time.timer++; - } - - cout << "fifo" << endl; - 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); - 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.ptr = 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; - - - switch(temp[temp1]){ - case 1: - fifo(); - break; - default: - cout << "enter fifo" << endl; - } - - cout << processes[0].in_cpu << endl; - cout << processes[0].ptr << endl; - - cout << processes[1].in_cpu << endl; - cout << processes[1].ptr << endl; - return 0; -} - - - - - - -I am writing the above code to as an answer for the following question: -Process Scheduling -Laboratory 3 -Duration: 3 weeks -This assignment will help us learn different process scheduling algorithms and their relative pros -and cons. -To do this task, you will need to develop a simulator of a scheduler in C / C++. The simulator -must take in the following command line arguments: -. The simulator must produce as output the following metrics: -Makespan, Completion Time (average and maximum), and Waiting Time (average and -maximum), Run Time of your simulator (not counting I/O). Also, report the schedule itself -(choose a nice format which will also help you debug). -For all the studies, we will use the workload description files given here. Each row in the file -refers to one process. The row format is as follows: - - … -1 -For example: -0 100 2 200 3 25 -1 indicates arrival time = 0; CPU burst 1 duration = 100; I/O burst 1 duration = -2; CPU burst 2 duration = 200; I/O burst 2 duration = 3; CPU burst 3 duration = 25; end of -process. -Assume that every line ends with -1. A process may have any number of CPU / I/O burst -cycles terminated with a -1. There will be any number of processes, terminated by an end of file. -The arrival times are in nondecreasing order. -Part I -Implement the following algorithms: -A. First In First Out - - -Also here is the input file: - - -
-0 100 2 -1
-2 80 2 -1
-
- - -Help me write the appropriate code