From 80127bbeb6ab9caee7e6aa9525f0ea44599e9d69 Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:29:19 +0530 Subject: [PATCH 01/18] Create non_preemptive_sjf_scheduling.cpp --- non_preemptive_sjf_scheduling.cpp | 296 ++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 non_preemptive_sjf_scheduling.cpp diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp new file mode 100644 index 00000000000..f55ac529ae5 --- /dev/null +++ b/non_preemptive_sjf_scheduling.cpp @@ -0,0 +1,296 @@ +/** + * @file + * @brief Implementation of SJF CPU scheduling algorithm + * @details + * shortest job first (SJF), also known as shortest job next (SJN), is a scheduling policy + * that selects for execution the waiting process with the smallest execution time. + * SJN is a non-preemptive algorithm. Shortest remaining time is a preemptive variant of SJN. + * @link https://www.guru99.com/shortest-job-first-sjf-scheduling.html + * @author [Lakshmi Srikumar](https://github.com/LakshmiSrikumar) + */ + +#include /// for sorting +#include /// for assert +#include /// random number generation +#include /// for time +#include /// for formatting the output +#include /// for IO operations +#include /// for std::priority_queue +#include /// for std::unordered_set +#include /// for std::vector + +using std::cin; +using std::cout; +using std::endl; +using std::get; +using std::left; +using std::make_tuple; +using std::priority_queue; +using std::rand; +using std::srand; +using std::tuple; +using std::unordered_set; +using std::vector; + +/** + * @brief Comparator function for sorting a vector + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + * @param t1 First tuple + * @param t2 Second tuple + * @returns true if t1 and t2 are in the CORRECT order + * @returns false if t1 and t2 are in the INCORRECT order + */ +template +bool sortcol(tuple& t1, tuple& t2) { + if (get<1>(t1) < get<1>(t2)) { + return true; + } else if (get<1>(t1) == get<1>(t2) && get<0>(t1) < get<0>(t2)) { + return true; + } + return false; +} + +/** + * @class Compare + * @brief Comparator class for priority queue + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + */ + +template +class Compare { + public: + + /** + * @param t1 First tuple + * @param t2 Second tuple + * @brief A comparator function that checks whether to swap the two tuples + * or not. + * @link Refer to + * https://www.geeksforgeeks.org/comparator-class-in-c-with-examples/ for + * detailed description of comparator + * @returns true if the tuples SHOULD be swapped + * @returns false if the tuples SHOULDN'T be swapped + */ + + bool operator()(tuple& t1, + tuple& t2) { + // Compare burst times for SJF + if (get<2>(t2) < get<2>(t1)) { + return true; + } + // If burst times are the same, compare arrival times + else if (get<2>(t2) == get<2>(t1)) { + return get<1>(t2) < get<1>(t1); + } + return false; + } +}; + +/** + * @class SJF + * @brief Class which implements the SJF scheduling algorithm + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + */ +template +class SJF { +/** + * Priority queue of schedules(stored as tuples) of processes. + * In each tuple + * 1st element: Process ID + * 2nd element: Arrival Time + * 3rd element: Burst time + * 4th element: Completion time + * 5th element: Turnaround time + * 6th element: Waiting time + */ + priority_queue, + vector>, + Compare> schedule; + + // Stores final status of all the processes after completing the execution. + vector> result; + + // Stores process IDs. Used for confirming absence of a process while it. + unordered_set idList; + + public: + /** + * @brief Adds the process to the ready queue if it isn't already there + * @param id Process ID + * @param arrival Arrival time of the process + * @param burst Burst time of the process + * @returns void + * + */ + void addProcess(S id, T arrival, E burst) { + // Add if a process with process ID as id is not found in idList. + if (idList.find(id) == idList.end()) { + tuple t = + make_tuple(id, arrival, burst, 0, 0, 0); + schedule.push(t); + idList.insert(id); + } + } + + /** + * @brief Algorithm for scheduling CPU processes according to the Shortest Job + First (SJF) scheduling algorithm. + * + * @details Non pre-emptive SJF is an algorithm that schedules processes based on the length + * of their burst times. The process with the smallest burst time is executed first. + * In a non-preemptive scheduling algorithm, once a process starts executing, + * it runs to completion without being interrupted. + * + * I used a min priority queue because it allows you to efficiently pick the process + * with the smallest burst time in constant time, by maintaining a priority order where + * the shortest burst process is always at the front. + * + * @returns void + */ + + vector> scheduleForSJF() { + // Variable to keep track of time elapsed so far + double timeElapsed = 0; + + while (!schedule.empty()) { + tuple cur = schedule.top(); + + // If the current process arrived at time t2, the last process + // completed its execution at time t1, and t2 > t1. + if (get<1>(cur) > timeElapsed) { + timeElapsed += get<1>(cur) - timeElapsed; + } + + // Add Burst time to time elapsed + timeElapsed += get<2>(cur); + + // Completion time of the current process will be same as time + // elapsed so far + get<3>(cur) = timeElapsed; + + // Turnaround time = Completion time - Arrival time + get<4>(cur) = get<3>(cur) - get<1>(cur); + + // Waiting time = Turnaround time - Burst time + get<5>(cur) = get<4>(cur) - get<2>(cur); + + result.push_back(cur); + schedule.pop(); + } + return result; + } + /** + * @brief Utility function for printing the status of each process after + * execution + * @returns void + */ + + void printResult() { + cout << "Status of all processes post completion is as follows:" << endl; + + cout << std::setw(17) << left << "Process ID" << std::setw(17) << left + << "Arrival Time" << std::setw(17) << left << "Burst Time" + << std::setw(17) << left << "Completion Time" << std::setw(17) + << left << "Turnaround Time" << std::setw(17) << left + << "Waiting Time" << endl; + + for (size_t i{}; i < result.size(); i++) { + cout << std::setprecision(2) << std::fixed << std::setw(17) << left + << get<0>(result[i]) << std::setw(17) << left + << get<1>(result[i]) << std::setw(17) << left + << get<2>(result[i]) << std::setw(17) << left + << get<3>(result[i]) << std::setw(17) << left + << get<4>(result[i]) << std::setw(17) << left + << get<5>(result[i]) << endl; + } + } +}; + + /** + * @brief Computes the final status of processes after applying non-preemptive SJF scheduling + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + * @param input A vector of tuples containing Process ID, Arrival time, and Burst time + * @returns A vector of tuples containing Process ID, Arrival time, Burst time, + * Completion time, Turnaround time, and Waiting time + */ + + template + vector> get_final_status( + vector> input) { + + // Sort the processes based on Arrival time and then Burst time + sort(input.begin(), input.end(), sortcol); + + // Result vector to hold the final status of each process + vector> result(input.size()); + double timeElapsed = 0; + + for (size_t i = 0; i < input.size(); i++) { + // Extract Arrival time and Burst time + T arrival = get<1>(input[i]); + E burst = get<2>(input[i]); + + // If the CPU is idle, move time to the arrival of the next process + if (arrival > timeElapsed) { + timeElapsed = arrival; + } + + // Update timeElapsed by adding the burst time + timeElapsed += burst; + + // Calculate Completion time, Turnaround time, and Waiting time + double completion = timeElapsed; + double turnaround = completion - arrival; + double waiting = turnaround - burst; + + // Store the results in the result vector + result[i] = make_tuple(get<0>(input[i]), arrival, burst, completion, turnaround, waiting); + } + + return result; + } + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + for (int i{}; i < 1000; i++) { + srand(time(nullptr)); + uint32_t n = 1 + rand() % 1000; + SJF readyQueue; + vector> input(n); + + for (uint32_t i{}; i < n; i++) { + get<0>(input[i]) = i; + srand(time(nullptr)); + get<1>(input[i]) = 1 + rand() % 10000; + srand(time(nullptr)); + get<2>(input[i]) = 1 + rand() % 10000; + } + + for (uint32_t i{}; i < n; i++) { + readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]), + get<2>(input[i])); + } + readyQueue.scheduleForSJF(); + //readyQueue.printResult(); + } + cout << "All the tests have successfully passed!" << endl; +} + +/** + * @brief Entry point of the program + */ +int main() { + test(); + return 0; +} From ad156c94e85188fb075fc664bb1b426ead386999 Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:57:51 +0530 Subject: [PATCH 02/18] Update non_preemptive_sjf_scheduling.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- non_preemptive_sjf_scheduling.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp index f55ac529ae5..97185a8ea0b 100644 --- a/non_preemptive_sjf_scheduling.cpp +++ b/non_preemptive_sjf_scheduling.cpp @@ -59,7 +59,6 @@ bool sortcol(tuple& t1, tuple& t2) { * @tparam T Data type of Arrival time * @tparam E Data type of Burst time */ - template class Compare { public: From b8e1b8484030fbea86cd931ac5d56762a77d71d3 Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:58:51 +0530 Subject: [PATCH 03/18] Update non_preemptive_sjf_scheduling.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- non_preemptive_sjf_scheduling.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp index 97185a8ea0b..d6c2794b308 100644 --- a/non_preemptive_sjf_scheduling.cpp +++ b/non_preemptive_sjf_scheduling.cpp @@ -74,7 +74,6 @@ class Compare { * @returns true if the tuples SHOULD be swapped * @returns false if the tuples SHOULDN'T be swapped */ - bool operator()(tuple& t1, tuple& t2) { // Compare burst times for SJF From d00becf20cb5f4b527e29421fe9c5dad231a7435 Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:59:12 +0530 Subject: [PATCH 04/18] Update non_preemptive_sjf_scheduling.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- non_preemptive_sjf_scheduling.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp index d6c2794b308..ea4f98d926c 100644 --- a/non_preemptive_sjf_scheduling.cpp +++ b/non_preemptive_sjf_scheduling.cpp @@ -219,7 +219,6 @@ class SJF { * @returns A vector of tuples containing Process ID, Arrival time, Burst time, * Completion time, Turnaround time, and Waiting time */ - template vector> get_final_status( vector> input) { From 7af8d8ae0a45fb5050aa7184d73e77250b769d87 Mon Sep 17 00:00:00 2001 From: LakshmiSrikumar <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:49:46 +0530 Subject: [PATCH 05/18] added a vector to store and print the final result --- non_preemptive_sjf_scheduling.cpp | 59 ++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp index ea4f98d926c..b470ca97dcb 100644 --- a/non_preemptive_sjf_scheduling.cpp +++ b/non_preemptive_sjf_scheduling.cpp @@ -11,8 +11,7 @@ #include /// for sorting #include /// for assert -#include /// random number generation -#include /// for time +#include /// random number generation #include /// for formatting the output #include /// for IO operations #include /// for std::priority_queue @@ -26,8 +25,6 @@ using std::get; using std::left; using std::make_tuple; using std::priority_queue; -using std::rand; -using std::srand; using std::tuple; using std::unordered_set; using std::vector; @@ -37,8 +34,8 @@ using std::vector; * @tparam S Data type of Process ID * @tparam T Data type of Arrival time * @tparam E Data type of Burst time - * @param t1 First tuple - * @param t2 Second tuple + * @param t1 First tuplet1 + * @param t2 Second tuplet2 * @returns true if t1 and t2 are in the CORRECT order * @returns false if t1 and t2 are in the INCORRECT order */ @@ -260,27 +257,55 @@ class SJF { * @returns void */ static void test() { - for (int i{}; i < 1000; i++) { - srand(time(nullptr)); - uint32_t n = 1 + rand() % 1000; + // A vector to store the results of all processes across all test cases. + vector> finalResult; + + for (int i{}; i < 100; i++) { + std::random_device rd; // Seeding + std::mt19937 eng(rd()); + std::uniform_int_distribution<> distr(1, 100); + + uint32_t n = distr(eng); SJF readyQueue; vector> input(n); + // Generate random arrival and burst times for (uint32_t i{}; i < n; i++) { get<0>(input[i]) = i; - srand(time(nullptr)); - get<1>(input[i]) = 1 + rand() % 10000; - srand(time(nullptr)); - get<2>(input[i]) = 1 + rand() % 10000; + get<1>(input[i]) = distr(eng); // Random arrival time + get<2>(input[i]) = distr(eng); // Random burst time } + // Add processes to the queue for (uint32_t i{}; i < n; i++) { - readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]), - get<2>(input[i])); + readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]), get<2>(input[i])); } - readyQueue.scheduleForSJF(); - //readyQueue.printResult(); + + // Schedule processes using SJF + vector> beforeResult = readyQueue.scheduleForSJF(); + + // Append the results of this test case to the final result + finalResult.insert(finalResult.end(), partialResult.begin(), partialResult.end()); } + + // Now, print the results after all test cases + cout << "Status of all processes post completion is as follows:" << endl; + cout << std::setw(17) << left << "Process ID" << std::setw(17) << left + << "Arrival Time" << std::setw(17) << left << "Burst Time" + << std::setw(17) << left << "Completion Time" << std::setw(17) + << left << "Turnaround Time" << std::setw(17) << left << "Waiting Time" << endl; + + // Loop through the final result and print all process details + for (size_t i{}; i < finalResult.size(); i++) { + cout << std::setprecision(2) << std::fixed << std::setw(17) << left + << get<0>(finalResult[i]) << std::setw(17) << left + << get<1>(finalResult[i]) << std::setw(17) << left + << get<2>(finalResult[i]) << std::setw(17) << left + << get<3>(finalResult[i]) << std::setw(17) << left + << get<4>(finalResult[i]) << std::setw(17) << left + << get<5>(finalResult[i]) << endl; + } + cout << "All the tests have successfully passed!" << endl; } From 062a78c0abc702ab41cd218b7b740f7591fa1bdd Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:45:14 +0530 Subject: [PATCH 06/18] Update non_preemptive_sjf_scheduling.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- non_preemptive_sjf_scheduling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp index b470ca97dcb..4f372bf05c1 100644 --- a/non_preemptive_sjf_scheduling.cpp +++ b/non_preemptive_sjf_scheduling.cpp @@ -35,7 +35,7 @@ using std::vector; * @tparam T Data type of Arrival time * @tparam E Data type of Burst time * @param t1 First tuplet1 - * @param t2 Second tuplet2 + * @param t2 tuple containing process id, arrival time and burst time * @returns true if t1 and t2 are in the CORRECT order * @returns false if t1 and t2 are in the INCORRECT order */ From 77402aa4088620f4ebbba3a700872ec380bf1019 Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:45:54 +0530 Subject: [PATCH 07/18] Update non_preemptive_sjf_scheduling.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- non_preemptive_sjf_scheduling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp index 4f372bf05c1..d093623b07a 100644 --- a/non_preemptive_sjf_scheduling.cpp +++ b/non_preemptive_sjf_scheduling.cpp @@ -34,7 +34,7 @@ using std::vector; * @tparam S Data type of Process ID * @tparam T Data type of Arrival time * @tparam E Data type of Burst time - * @param t1 First tuplet1 + * @param t1 tuple containing process id, arrival time and burst time * @param t2 tuple containing process id, arrival time and burst time * @returns true if t1 and t2 are in the CORRECT order * @returns false if t1 and t2 are in the INCORRECT order From 9d9b51f2d996c3615baf69db267ab1b488dfa8ee Mon Sep 17 00:00:00 2001 From: LakshmiSrikumar <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Sat, 12 Oct 2024 11:04:34 +0530 Subject: [PATCH 08/18] Create non_preemptive_sjf_scheduling.cpp I have done the necessary changes. The test function will generate 10 different testcases in which it will print the before and after the SJF scheduling. @realstealthninja Kindly review the PR and please accept it. --- .../non_preemptive_sjf_scheduling.cpp | 306 ++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp diff --git a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp new file mode 100644 index 00000000000..90fc993a1cb --- /dev/null +++ b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp @@ -0,0 +1,306 @@ +/** + * @file + * @brief Implementation of SJF CPU scheduling algorithm + * @details + * shortest job first (SJF), also known as shortest job next (SJN), is a scheduling policy + * that selects for execution the waiting process with the smallest execution time. + * SJN is a non-preemptive algorithm. Shortest remaining time is a preemptive variant of SJN. + * @link https://www.guru99.com/shortest-job-first-sjf-scheduling.html + * @author [Lakshmi Srikumar](https://github.com/LakshmiSrikumar) + */ + +#include /// for sorting +#include /// for assert +#include /// random number generation +#include /// for formatting the output +#include /// for IO operations +#include /// for std::priority_queue +#include /// for std::unordered_set +#include /// for std::vector + +using std::cin; +using std::cout; +using std::endl; +using std::get; +using std::left; +using std::make_tuple; +using std::priority_queue; +using std::tuple; +using std::unordered_set; +using std::vector; + +/** + * @brief Comparator function for sorting a vector + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + * @param t1 First tuplet1 + * @param t2 Second tuplet2 + * @returns true if t1 and t2 are in the CORRECT order + * @returns false if t1 and t2 are in the INCORRECT order + */ +template +bool sortcol(tuple& t1, tuple& t2) { + if (get<1>(t1) < get<1>(t2)) { + return true; + } else if (get<1>(t1) == get<1>(t2) && get<0>(t1) < get<0>(t2)) { + return true; + } + return false; +} + +/** + * @class Compare + * @brief Comparator class for priority queue + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + */ +template +class Compare { + public: + + /** + * @param t1 First tuple + * @param t2 Second tuple + * @brief A comparator function that checks whether to swap the two tuples + * or not. + * @link Refer to + * https://www.geeksforgeeks.org/comparator-class-in-c-with-examples/ for + * detailed description of comparator + * @returns true if the tuples SHOULD be swapped + * @returns false if the tuples SHOULDN'T be swapped + */ + bool operator()(tuple& t1, + tuple& t2) { + // Compare burst times for SJF + if (get<2>(t2) < get<2>(t1)) { + return true; + } + // If burst times are the same, compare arrival times + else if (get<2>(t2) == get<2>(t1)) { + return get<1>(t2) < get<1>(t1); + } + return false; + } +}; + +/** + * @class SJF + * @brief Class which implements the SJF scheduling algorithm + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + */ +template +class SJF { +/** + * Priority queue of schedules(stored as tuples) of processes. + * In each tuple + * 1st element: Process ID + * 2nd element: Arrival Time + * 3rd element: Burst time + * 4th element: Completion time + * 5th element: Turnaround time + * 6th element: Waiting time + */ + priority_queue, + vector>, + Compare> schedule; + + // Stores final status of all the processes after completing the execution. + vector> result; + + // Stores process IDs. Used for confirming absence of a process while it. + unordered_set idList; + + public: + /** + * @brief Adds the process to the ready queue if it isn't already there + * @param id Process ID + * @param arrival Arrival time of the process + * @param burst Burst time of the process + * @returns void + * + */ + void addProcess(S id, T arrival, E burst) { + // Add if a process with process ID as id is not found in idList. + if (idList.find(id) == idList.end()) { + tuple t = + make_tuple(id, arrival, burst, 0, 0, 0); + schedule.push(t); + idList.insert(id); + } + } + + /** + * @brief Algorithm for scheduling CPU processes according to the Shortest Job + First (SJF) scheduling algorithm. + * + * @details Non pre-emptive SJF is an algorithm that schedules processes based on the length + * of their burst times. The process with the smallest burst time is executed first. + * In a non-preemptive scheduling algorithm, once a process starts executing, + * it runs to completion without being interrupted. + * + * I used a min priority queue because it allows you to efficiently pick the process + * with the smallest burst time in constant time, by maintaining a priority order where + * the shortest burst process is always at the front. + * + * @returns void + */ + + vector> scheduleForSJF() { + // Variable to keep track of time elapsed so far + double timeElapsed = 0; + + while (!schedule.empty()) { + tuple cur = schedule.top(); + + // If the current process arrived at time t2, the last process + // completed its execution at time t1, and t2 > t1. + if (get<1>(cur) > timeElapsed) { + timeElapsed += get<1>(cur) - timeElapsed; + } + + // Add Burst time to time elapsed + timeElapsed += get<2>(cur); + + // Completion time of the current process will be same as time + // elapsed so far + get<3>(cur) = timeElapsed; + + // Turnaround time = Completion time - Arrival time + get<4>(cur) = get<3>(cur) - get<1>(cur); + + // Waiting time = Turnaround time - Burst time + get<5>(cur) = get<4>(cur) - get<2>(cur); + + result.push_back(cur); + schedule.pop(); + } + return result; + } + /** + * @brief Utility function for printing the status of each process after + * execution + * @returns void + */ + + void printResult(const vector>& processes) { + + cout << std::setw(17) << left << "Process ID" << std::setw(17) << left + << "Arrival Time" << std::setw(17) << left << "Burst Time" + << std::setw(17) << left << "Completion Time" << std::setw(17) + << left << "Turnaround Time" << std::setw(17) << left + << "Waiting Time" << endl; + + for (const auto& process : processes) { + cout << std::setprecision(2) << std::fixed << std::setw(17) << left + << get<0>(process) << std::setw(17) << left + << get<1>(process) << std::setw(17) << left + << get<2>(process) << std::setw(17) << left + << get<3>(process) << std::setw(17) << left + << get<4>(process) << std::setw(17) << left + << get<5>(process) << endl; + } + } +}; + + /** + * @brief Computes the final status of processes after applying non-preemptive SJF scheduling + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + * @param input A vector of tuples containing Process ID, Arrival time, and Burst time + * @returns A vector of tuples containing Process ID, Arrival time, Burst time, + * Completion time, Turnaround time, and Waiting time + */ + template + vector> get_final_status( + vector> input) { + + // Sort the processes based on Arrival time and then Burst time + sort(input.begin(), input.end(), sortcol); + + // Result vector to hold the final status of each process + vector> result(input.size()); + double timeElapsed = 0; + + for (size_t i = 0; i < input.size(); i++) { + // Extract Arrival time and Burst time + T arrival = get<1>(input[i]); + E burst = get<2>(input[i]); + + // If the CPU is idle, move time to the arrival of the next process + if (arrival > timeElapsed) { + timeElapsed = arrival; + } + + // Update timeElapsed by adding the burst time + timeElapsed += burst; + + // Calculate Completion time, Turnaround time, and Waiting time + double completion = timeElapsed; + double turnaround = completion - arrival; + double waiting = turnaround - burst; + + // Store the results in the result vector + result[i] = make_tuple(get<0>(input[i]), arrival, burst, completion, turnaround, waiting); + } + + return result; + } + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + // A vector to store the results of all processes across all test cases. + vector> finalResult; + + for (int i{}; i < 10; i++) { + std::random_device rd; // Seeding + std::mt19937 eng(rd()); + std::uniform_int_distribution<> distr(1, 10); + + uint32_t n = distr(eng); + SJF readyQueue; + vector> input(n); + + // Generate random arrival and burst times + for (uint32_t i{}; i < n; i++) { + get<0>(input[i]) = i; + get<1>(input[i]) = distr(eng); // Random arrival time + get<2>(input[i]) = distr(eng); // Random burst time + } + + // Print processes before scheduling + cout << "Processes before SJF scheduling:" << endl; + readyQueue.printResult(input); + + // Add processes to the queue + for (uint32_t i{}; i < n; i++) { + readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]), get<2>(input[i])); + } + + // Perform SJF scheduling + auto finalResult = readyQueue.scheduleForSJF(); + + // Print processes after scheduling + cout << "\nProcesses after SJF scheduling:" << endl; + readyQueue.printResult(finalResult); + } + cout << "All the tests have successfully passed!" << endl; + } + + + + +/** + * @brief Entry point of the program + */ +int main() { + test(); + return 0; +} From 4404bbb4277d609b4d1715c75c5d11e7e617016b Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Sat, 12 Oct 2024 11:07:12 +0530 Subject: [PATCH 09/18] Delete non_preemptive_sjf_scheduling.cpp --- non_preemptive_sjf_scheduling.cpp | 318 ------------------------------ 1 file changed, 318 deletions(-) delete mode 100644 non_preemptive_sjf_scheduling.cpp diff --git a/non_preemptive_sjf_scheduling.cpp b/non_preemptive_sjf_scheduling.cpp deleted file mode 100644 index d093623b07a..00000000000 --- a/non_preemptive_sjf_scheduling.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/** - * @file - * @brief Implementation of SJF CPU scheduling algorithm - * @details - * shortest job first (SJF), also known as shortest job next (SJN), is a scheduling policy - * that selects for execution the waiting process with the smallest execution time. - * SJN is a non-preemptive algorithm. Shortest remaining time is a preemptive variant of SJN. - * @link https://www.guru99.com/shortest-job-first-sjf-scheduling.html - * @author [Lakshmi Srikumar](https://github.com/LakshmiSrikumar) - */ - -#include /// for sorting -#include /// for assert -#include /// random number generation -#include /// for formatting the output -#include /// for IO operations -#include /// for std::priority_queue -#include /// for std::unordered_set -#include /// for std::vector - -using std::cin; -using std::cout; -using std::endl; -using std::get; -using std::left; -using std::make_tuple; -using std::priority_queue; -using std::tuple; -using std::unordered_set; -using std::vector; - -/** - * @brief Comparator function for sorting a vector - * @tparam S Data type of Process ID - * @tparam T Data type of Arrival time - * @tparam E Data type of Burst time - * @param t1 tuple containing process id, arrival time and burst time - * @param t2 tuple containing process id, arrival time and burst time - * @returns true if t1 and t2 are in the CORRECT order - * @returns false if t1 and t2 are in the INCORRECT order - */ -template -bool sortcol(tuple& t1, tuple& t2) { - if (get<1>(t1) < get<1>(t2)) { - return true; - } else if (get<1>(t1) == get<1>(t2) && get<0>(t1) < get<0>(t2)) { - return true; - } - return false; -} - -/** - * @class Compare - * @brief Comparator class for priority queue - * @tparam S Data type of Process ID - * @tparam T Data type of Arrival time - * @tparam E Data type of Burst time - */ -template -class Compare { - public: - - /** - * @param t1 First tuple - * @param t2 Second tuple - * @brief A comparator function that checks whether to swap the two tuples - * or not. - * @link Refer to - * https://www.geeksforgeeks.org/comparator-class-in-c-with-examples/ for - * detailed description of comparator - * @returns true if the tuples SHOULD be swapped - * @returns false if the tuples SHOULDN'T be swapped - */ - bool operator()(tuple& t1, - tuple& t2) { - // Compare burst times for SJF - if (get<2>(t2) < get<2>(t1)) { - return true; - } - // If burst times are the same, compare arrival times - else if (get<2>(t2) == get<2>(t1)) { - return get<1>(t2) < get<1>(t1); - } - return false; - } -}; - -/** - * @class SJF - * @brief Class which implements the SJF scheduling algorithm - * @tparam S Data type of Process ID - * @tparam T Data type of Arrival time - * @tparam E Data type of Burst time - */ -template -class SJF { -/** - * Priority queue of schedules(stored as tuples) of processes. - * In each tuple - * 1st element: Process ID - * 2nd element: Arrival Time - * 3rd element: Burst time - * 4th element: Completion time - * 5th element: Turnaround time - * 6th element: Waiting time - */ - priority_queue, - vector>, - Compare> schedule; - - // Stores final status of all the processes after completing the execution. - vector> result; - - // Stores process IDs. Used for confirming absence of a process while it. - unordered_set idList; - - public: - /** - * @brief Adds the process to the ready queue if it isn't already there - * @param id Process ID - * @param arrival Arrival time of the process - * @param burst Burst time of the process - * @returns void - * - */ - void addProcess(S id, T arrival, E burst) { - // Add if a process with process ID as id is not found in idList. - if (idList.find(id) == idList.end()) { - tuple t = - make_tuple(id, arrival, burst, 0, 0, 0); - schedule.push(t); - idList.insert(id); - } - } - - /** - * @brief Algorithm for scheduling CPU processes according to the Shortest Job - First (SJF) scheduling algorithm. - * - * @details Non pre-emptive SJF is an algorithm that schedules processes based on the length - * of their burst times. The process with the smallest burst time is executed first. - * In a non-preemptive scheduling algorithm, once a process starts executing, - * it runs to completion without being interrupted. - * - * I used a min priority queue because it allows you to efficiently pick the process - * with the smallest burst time in constant time, by maintaining a priority order where - * the shortest burst process is always at the front. - * - * @returns void - */ - - vector> scheduleForSJF() { - // Variable to keep track of time elapsed so far - double timeElapsed = 0; - - while (!schedule.empty()) { - tuple cur = schedule.top(); - - // If the current process arrived at time t2, the last process - // completed its execution at time t1, and t2 > t1. - if (get<1>(cur) > timeElapsed) { - timeElapsed += get<1>(cur) - timeElapsed; - } - - // Add Burst time to time elapsed - timeElapsed += get<2>(cur); - - // Completion time of the current process will be same as time - // elapsed so far - get<3>(cur) = timeElapsed; - - // Turnaround time = Completion time - Arrival time - get<4>(cur) = get<3>(cur) - get<1>(cur); - - // Waiting time = Turnaround time - Burst time - get<5>(cur) = get<4>(cur) - get<2>(cur); - - result.push_back(cur); - schedule.pop(); - } - return result; - } - /** - * @brief Utility function for printing the status of each process after - * execution - * @returns void - */ - - void printResult() { - cout << "Status of all processes post completion is as follows:" << endl; - - cout << std::setw(17) << left << "Process ID" << std::setw(17) << left - << "Arrival Time" << std::setw(17) << left << "Burst Time" - << std::setw(17) << left << "Completion Time" << std::setw(17) - << left << "Turnaround Time" << std::setw(17) << left - << "Waiting Time" << endl; - - for (size_t i{}; i < result.size(); i++) { - cout << std::setprecision(2) << std::fixed << std::setw(17) << left - << get<0>(result[i]) << std::setw(17) << left - << get<1>(result[i]) << std::setw(17) << left - << get<2>(result[i]) << std::setw(17) << left - << get<3>(result[i]) << std::setw(17) << left - << get<4>(result[i]) << std::setw(17) << left - << get<5>(result[i]) << endl; - } - } -}; - - /** - * @brief Computes the final status of processes after applying non-preemptive SJF scheduling - * @tparam S Data type of Process ID - * @tparam T Data type of Arrival time - * @tparam E Data type of Burst time - * @param input A vector of tuples containing Process ID, Arrival time, and Burst time - * @returns A vector of tuples containing Process ID, Arrival time, Burst time, - * Completion time, Turnaround time, and Waiting time - */ - template - vector> get_final_status( - vector> input) { - - // Sort the processes based on Arrival time and then Burst time - sort(input.begin(), input.end(), sortcol); - - // Result vector to hold the final status of each process - vector> result(input.size()); - double timeElapsed = 0; - - for (size_t i = 0; i < input.size(); i++) { - // Extract Arrival time and Burst time - T arrival = get<1>(input[i]); - E burst = get<2>(input[i]); - - // If the CPU is idle, move time to the arrival of the next process - if (arrival > timeElapsed) { - timeElapsed = arrival; - } - - // Update timeElapsed by adding the burst time - timeElapsed += burst; - - // Calculate Completion time, Turnaround time, and Waiting time - double completion = timeElapsed; - double turnaround = completion - arrival; - double waiting = turnaround - burst; - - // Store the results in the result vector - result[i] = make_tuple(get<0>(input[i]), arrival, burst, completion, turnaround, waiting); - } - - return result; - } - -/** - * @brief Self-test implementations - * @returns void - */ -static void test() { - // A vector to store the results of all processes across all test cases. - vector> finalResult; - - for (int i{}; i < 100; i++) { - std::random_device rd; // Seeding - std::mt19937 eng(rd()); - std::uniform_int_distribution<> distr(1, 100); - - uint32_t n = distr(eng); - SJF readyQueue; - vector> input(n); - - // Generate random arrival and burst times - for (uint32_t i{}; i < n; i++) { - get<0>(input[i]) = i; - get<1>(input[i]) = distr(eng); // Random arrival time - get<2>(input[i]) = distr(eng); // Random burst time - } - - // Add processes to the queue - for (uint32_t i{}; i < n; i++) { - readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]), get<2>(input[i])); - } - - // Schedule processes using SJF - vector> beforeResult = readyQueue.scheduleForSJF(); - - // Append the results of this test case to the final result - finalResult.insert(finalResult.end(), partialResult.begin(), partialResult.end()); - } - - // Now, print the results after all test cases - cout << "Status of all processes post completion is as follows:" << endl; - cout << std::setw(17) << left << "Process ID" << std::setw(17) << left - << "Arrival Time" << std::setw(17) << left << "Burst Time" - << std::setw(17) << left << "Completion Time" << std::setw(17) - << left << "Turnaround Time" << std::setw(17) << left << "Waiting Time" << endl; - - // Loop through the final result and print all process details - for (size_t i{}; i < finalResult.size(); i++) { - cout << std::setprecision(2) << std::fixed << std::setw(17) << left - << get<0>(finalResult[i]) << std::setw(17) << left - << get<1>(finalResult[i]) << std::setw(17) << left - << get<2>(finalResult[i]) << std::setw(17) << left - << get<3>(finalResult[i]) << std::setw(17) << left - << get<4>(finalResult[i]) << std::setw(17) << left - << get<5>(finalResult[i]) << endl; - } - - cout << "All the tests have successfully passed!" << endl; -} - -/** - * @brief Entry point of the program - */ -int main() { - test(); - return 0; -} From ccb3f072082328b843610bdd655daf11069db9ef Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Sat, 12 Oct 2024 14:06:31 +0530 Subject: [PATCH 10/18] Update cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp index 90fc993a1cb..bbc05c0563f 100644 --- a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp +++ b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp @@ -65,9 +65,7 @@ class Compare { * @param t2 Second tuple * @brief A comparator function that checks whether to swap the two tuples * or not. - * @link Refer to - * https://www.geeksforgeeks.org/comparator-class-in-c-with-examples/ for - * detailed description of comparator + * detailed description of comparator * @returns true if the tuples SHOULD be swapped * @returns false if the tuples SHOULDN'T be swapped */ From cbbfc88fa9c7b97b9af5570d01761ca2601ce6d1 Mon Sep 17 00:00:00 2001 From: LakshmiSrikumar <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Sat, 12 Oct 2024 14:38:00 +0530 Subject: [PATCH 11/18] Update non_preemptive_sjf_scheduling.cpp --- .../non_preemptive_sjf_scheduling.cpp | 204 +++++++++--------- 1 file changed, 106 insertions(+), 98 deletions(-) diff --git a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp index bbc05c0563f..0b0de343da5 100644 --- a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp +++ b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp @@ -2,21 +2,22 @@ * @file * @brief Implementation of SJF CPU scheduling algorithm * @details - * shortest job first (SJF), also known as shortest job next (SJN), is a scheduling policy - * that selects for execution the waiting process with the smallest execution time. - * SJN is a non-preemptive algorithm. Shortest remaining time is a preemptive variant of SJN. + * shortest job first (SJF), also known as shortest job next (SJN), is a + * scheduling policy that selects for execution the waiting process with the + * smallest execution time. SJN is a non-preemptive algorithm. Shortest + * remaining time is a preemptive variant of SJN. * @link https://www.guru99.com/shortest-job-first-sjf-scheduling.html * @author [Lakshmi Srikumar](https://github.com/LakshmiSrikumar) */ -#include /// for sorting -#include /// for assert -#include /// random number generation -#include /// for formatting the output -#include /// for IO operations -#include /// for std::priority_queue -#include /// for std::unordered_set -#include /// for std::vector +#include /// for sorting +#include /// for assert +#include /// for formatting the output +#include /// for IO operations +#include /// for std::priority_queue +#include /// random number generation +#include /// for std::unordered_set +#include /// for std::vector using std::cin; using std::cout; @@ -59,13 +60,14 @@ bool sortcol(tuple& t1, tuple& t2) { template class Compare { public: - - /** + /** * @param t1 First tuple * @param t2 Second tuple * @brief A comparator function that checks whether to swap the two tuples * or not. - * detailed description of comparator + * + * detailed description of comparator * @returns true if the tuples SHOULD be swapped * @returns false if the tuples SHOULDN'T be swapped */ @@ -92,7 +94,7 @@ class Compare { */ template class SJF { -/** + /** * Priority queue of schedules(stored as tuples) of processes. * In each tuple * 1st element: Process ID @@ -104,16 +106,17 @@ class SJF { */ priority_queue, vector>, - Compare> schedule; - + Compare> + schedule; + // Stores final status of all the processes after completing the execution. vector> result; - + // Stores process IDs. Used for confirming absence of a process while it. unordered_set idList; public: - /** + /** * @brief Adds the process to the ready queue if it isn't already there * @param id Process ID * @param arrival Arrival time of the process @@ -122,7 +125,7 @@ class SJF { * */ void addProcess(S id, T arrival, E burst) { - // Add if a process with process ID as id is not found in idList. + // Add if a process with process ID as id is not found in idList. if (idList.find(id) == idList.end()) { tuple t = make_tuple(id, arrival, burst, 0, 0, 0); @@ -131,35 +134,39 @@ class SJF { } } - /** - * @brief Algorithm for scheduling CPU processes according to the Shortest Job - First (SJF) scheduling algorithm. - * - * @details Non pre-emptive SJF is an algorithm that schedules processes based on the length - * of their burst times. The process with the smallest burst time is executed first. - * In a non-preemptive scheduling algorithm, once a process starts executing, - * it runs to completion without being interrupted. - * - * I used a min priority queue because it allows you to efficiently pick the process - * with the smallest burst time in constant time, by maintaining a priority order where - * the shortest burst process is always at the front. - * - * @returns void - */ + /** + * @brief Algorithm for scheduling CPU processes according to the Shortest Job + First (SJF) scheduling algorithm. + * + * @details Non pre-emptive SJF is an algorithm that schedules processes based + on the length + * of their burst times. The process with the smallest burst time is executed + first. + * In a non-preemptive scheduling algorithm, once a process starts executing, + * it runs to completion without being interrupted. + * + * I used a min priority queue because it allows you to efficiently pick the + process + * with the smallest burst time in constant time, by maintaining a priority + order where + * the shortest burst process is always at the front. + * + * @returns void + */ vector> scheduleForSJF() { - // Variable to keep track of time elapsed so far + // Variable to keep track of time elapsed so far double timeElapsed = 0; while (!schedule.empty()) { tuple cur = schedule.top(); - - // If the current process arrived at time t2, the last process + + // If the current process arrived at time t2, the last process // completed its execution at time t1, and t2 > t1. if (get<1>(cur) > timeElapsed) { timeElapsed += get<1>(cur) - timeElapsed; } - + // Add Burst time to time elapsed timeElapsed += get<2>(cur); @@ -184,8 +191,8 @@ class SJF { * @returns void */ - void printResult(const vector>& processes) { - + void printResult( + const vector>& processes) { cout << std::setw(17) << left << "Process ID" << std::setw(17) << left << "Arrival Time" << std::setw(17) << left << "Burst Time" << std::setw(17) << left << "Completion Time" << std::setw(17) @@ -194,60 +201,61 @@ class SJF { for (const auto& process : processes) { cout << std::setprecision(2) << std::fixed << std::setw(17) << left - << get<0>(process) << std::setw(17) << left - << get<1>(process) << std::setw(17) << left - << get<2>(process) << std::setw(17) << left - << get<3>(process) << std::setw(17) << left - << get<4>(process) << std::setw(17) << left - << get<5>(process) << endl; + << get<0>(process) << std::setw(17) << left << get<1>(process) + << std::setw(17) << left << get<2>(process) << std::setw(17) + << left << get<3>(process) << std::setw(17) << left + << get<4>(process) << std::setw(17) << left << get<5>(process) + << endl; } } }; - /** - * @brief Computes the final status of processes after applying non-preemptive SJF scheduling - * @tparam S Data type of Process ID - * @tparam T Data type of Arrival time - * @tparam E Data type of Burst time - * @param input A vector of tuples containing Process ID, Arrival time, and Burst time - * @returns A vector of tuples containing Process ID, Arrival time, Burst time, - * Completion time, Turnaround time, and Waiting time - */ - template - vector> get_final_status( - vector> input) { - - // Sort the processes based on Arrival time and then Burst time - sort(input.begin(), input.end(), sortcol); - - // Result vector to hold the final status of each process - vector> result(input.size()); - double timeElapsed = 0; - - for (size_t i = 0; i < input.size(); i++) { +/** + * @brief Computes the final status of processes after applying non-preemptive + * SJF scheduling + * @tparam S Data type of Process ID + * @tparam T Data type of Arrival time + * @tparam E Data type of Burst time + * @param input A vector of tuples containing Process ID, Arrival time, and + * Burst time + * @returns A vector of tuples containing Process ID, Arrival time, Burst time, + * Completion time, Turnaround time, and Waiting time + */ +template +vector> get_final_status( + vector> input) { + // Sort the processes based on Arrival time and then Burst time + sort(input.begin(), input.end(), sortcol); + + // Result vector to hold the final status of each process + vector> result(input.size()); + double timeElapsed = 0; + + for (size_t i = 0; i < input.size(); i++) { // Extract Arrival time and Burst time - T arrival = get<1>(input[i]); - E burst = get<2>(input[i]); + T arrival = get<1>(input[i]); + E burst = get<2>(input[i]); - // If the CPU is idle, move time to the arrival of the next process - if (arrival > timeElapsed) { - timeElapsed = arrival; - } + // If the CPU is idle, move time to the arrival of the next process + if (arrival > timeElapsed) { + timeElapsed = arrival; + } - // Update timeElapsed by adding the burst time - timeElapsed += burst; + // Update timeElapsed by adding the burst time + timeElapsed += burst; - // Calculate Completion time, Turnaround time, and Waiting time - double completion = timeElapsed; - double turnaround = completion - arrival; - double waiting = turnaround - burst; + // Calculate Completion time, Turnaround time, and Waiting time + double completion = timeElapsed; + double turnaround = completion - arrival; + double waiting = turnaround - burst; - // Store the results in the result vector - result[i] = make_tuple(get<0>(input[i]), arrival, burst, completion, turnaround, waiting); - } - - return result; - } + // Store the results in the result vector + result[i] = make_tuple(get<0>(input[i]), arrival, burst, completion, + turnaround, waiting); + } + + return result; +} /** * @brief Self-test implementations @@ -255,16 +263,18 @@ class SJF { */ static void test() { // A vector to store the results of all processes across all test cases. - vector> finalResult; + vector> + finalResult; - for (int i{}; i < 10; i++) { - std::random_device rd; // Seeding + for (int i{}; i < 10; i++) { + std::random_device rd; // Seeding std::mt19937 eng(rd()); - std::uniform_int_distribution<> distr(1, 10); + std::uniform_int_distribution<> distr(1, 10); - uint32_t n = distr(eng); + uint32_t n = distr(eng); SJF readyQueue; - vector> input(n); + vector> + input(n); // Generate random arrival and burst times for (uint32_t i{}; i < n; i++) { @@ -279,10 +289,11 @@ static void test() { // Add processes to the queue for (uint32_t i{}; i < n; i++) { - readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]), get<2>(input[i])); + readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]), + get<2>(input[i])); } - // Perform SJF scheduling + // Perform SJF schedulings auto finalResult = readyQueue.scheduleForSJF(); // Print processes after scheduling @@ -290,10 +301,7 @@ static void test() { readyQueue.printResult(finalResult); } cout << "All the tests have successfully passed!" << endl; - } - - - +} /** * @brief Entry point of the program From 16d952f6fef599be066ed4340b6aed673a928495 Mon Sep 17 00:00:00 2001 From: LakshmiSrikumar <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:07:46 +0530 Subject: [PATCH 12/18] Update non_preemptive_sjf_scheduling.cpp --- .../non_preemptive_sjf_scheduling.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp index 0b0de343da5..d1935a4c88c 100644 --- a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp +++ b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp @@ -6,8 +6,9 @@ * scheduling policy that selects for execution the waiting process with the * smallest execution time. SJN is a non-preemptive algorithm. Shortest * remaining time is a preemptive variant of SJN. - * @link https://www.guru99.com/shortest-job-first-sjf-scheduling.html - * @author [Lakshmi Srikumar](https://github.com/LakshmiSrikumar) + * + * detailed description on SJF scheduling + * Author : Lakshmi Srikumar */ #include /// for sorting @@ -42,9 +43,8 @@ using std::vector; */ template bool sortcol(tuple& t1, tuple& t2) { - if (get<1>(t1) < get<1>(t2)) { - return true; - } else if (get<1>(t1) == get<1>(t2) && get<0>(t1) < get<0>(t2)) { + if (get<1>(t1) < get<1>(t2) || + (get<1>(t1) == get<1>(t2) && get<0>(t1) < get<0>(t2))) { return true; } return false; @@ -180,6 +180,12 @@ class SJF { // Waiting time = Turnaround time - Burst time get<5>(cur) = get<4>(cur) - get<2>(cur); + // Turnaround time >= Burst time + assert(get<4>(cur) >= get<2>(cur)); + + // Waiting time is never negative + assert(get<5>(cur) >= 0); + result.push_back(cur); schedule.pop(); } @@ -284,8 +290,8 @@ static void test() { } // Print processes before scheduling - cout << "Processes before SJF scheduling:" << endl; - readyQueue.printResult(input); + // cout << "Processes before SJF scheduling:" << endl; + // readyQueue.printResult(input); // Add processes to the queue for (uint32_t i{}; i < n; i++) { @@ -297,8 +303,8 @@ static void test() { auto finalResult = readyQueue.scheduleForSJF(); // Print processes after scheduling - cout << "\nProcesses after SJF scheduling:" << endl; - readyQueue.printResult(finalResult); + // cout << "\nProcesses after SJF scheduling:" << endl; + // readyQueue.printResult(finalResult); } cout << "All the tests have successfully passed!" << endl; } From d568897529c69a2d27c875ed678392b567fcf024 Mon Sep 17 00:00:00 2001 From: DoGoodCoder <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Sun, 13 Oct 2024 16:40:07 +0530 Subject: [PATCH 13/18] Update cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp index d1935a4c88c..7ce84841279 100644 --- a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp +++ b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp @@ -310,7 +310,8 @@ static void test() { } /** - * @brief Entry point of the program + * @brief Main function + * @returns 0 on successful exit */ int main() { test(); From 6ebca75a6649998932b1fa65a77bc54d06f69ea0 Mon Sep 17 00:00:00 2001 From: LakshmiSrikumar <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Sun, 13 Oct 2024 17:17:57 +0530 Subject: [PATCH 14/18] Update non_preemptive_sjf_scheduling.cpp --- .../non_preemptive_sjf_scheduling.cpp | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp index d1935a4c88c..fb2266b8dfc 100644 --- a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp +++ b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp @@ -135,24 +135,21 @@ class SJF { } /** - * @brief Algorithm for scheduling CPU processes according to the Shortest Job - First (SJF) scheduling algorithm. - * - * @details Non pre-emptive SJF is an algorithm that schedules processes based - on the length - * of their burst times. The process with the smallest burst time is executed - first. - * In a non-preemptive scheduling algorithm, once a process starts executing, - * it runs to completion without being interrupted. - * - * I used a min priority queue because it allows you to efficiently pick the - process - * with the smallest burst time in constant time, by maintaining a priority - order where - * the shortest burst process is always at the front. - * - * @returns void - */ + * @brief Algorithm for scheduling CPU processes according to + * the Shortest Job First (SJF) scheduling algorithm. + * + * @details Non pre-emptive SJF is an algorithm that schedules processes + * based on the length of their burst times. The process with the smallest + * burst time is executed first.In a non-preemptive scheduling algorithm, + * once a process starts executing,it runs to completion without being + * interrupted. + * + * I used a min priority queue because it allows you to efficiently pick the + * process with the smallest burst time in constant time, by maintaining a + * priority order where the shortest burst process is always at the front. + * + * @returns void + */ vector> scheduleForSJF() { // Variable to keep track of time elapsed so far @@ -192,8 +189,8 @@ class SJF { return result; } /** - * @brief Utility function for printing the status of each process after - * execution + * @brief Utility function for printing the status of + * each process after execution * @returns void */ @@ -217,8 +214,8 @@ class SJF { }; /** - * @brief Computes the final status of processes after applying non-preemptive - * SJF scheduling + * @brief Computes the final status of processes after + * applying non-preemptive SJF scheduling * @tparam S Data type of Process ID * @tparam T Data type of Arrival time * @tparam E Data type of Burst time @@ -290,8 +287,8 @@ static void test() { } // Print processes before scheduling - // cout << "Processes before SJF scheduling:" << endl; - // readyQueue.printResult(input); + cout << "Processes before SJF scheduling:" << endl; + readyQueue.printResult(input); // Add processes to the queue for (uint32_t i{}; i < n; i++) { @@ -303,8 +300,8 @@ static void test() { auto finalResult = readyQueue.scheduleForSJF(); // Print processes after scheduling - // cout << "\nProcesses after SJF scheduling:" << endl; - // readyQueue.printResult(finalResult); + cout << "\nProcesses after SJF scheduling:" << endl; + readyQueue.printResult(finalResult); } cout << "All the tests have successfully passed!" << endl; } From c195a7e06b41f984bf30b19efddab8679b339113 Mon Sep 17 00:00:00 2001 From: LakshmiSrikumar <141216093+LakshmiSrikumar@users.noreply.github.com> Date: Mon, 14 Oct 2024 11:06:05 +0530 Subject: [PATCH 15/18] Update non_preemptive_sjf_scheduling.cpp --- .../non_preemptive_sjf_scheduling.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp index a56928ac2bb..e7d9d370960 100644 --- a/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp +++ b/cpu_scheduling_algorithms/non_preemptive_sjf_scheduling.cpp @@ -97,12 +97,12 @@ class SJF { /** * Priority queue of schedules(stored as tuples) of processes. * In each tuple - * 1st element: Process ID - * 2nd element: Arrival Time - * 3rd element: Burst time - * 4th element: Completion time - * 5th element: Turnaround time - * 6th element: Waiting time + * @tparam 1st element: Process ID + * @tparam 2nd element: Arrival Time + * @tparam 3rd element: Burst time + * @tparam 4th element: Completion time + * @tparam 5th element: Turnaround time + * @tparam 6th element: Waiting time */ priority_queue, vector>, From a824301ee1e1e7ab9598f679ad97bcf6c4113f48 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 31 Oct 2024 05:14:52 +0000 Subject: [PATCH 16/18] clang-format and clang-tidy fixes for 57e670c2 --- .../{Unbounded_0_1_Knapsack.cpp => unbounded_0_1_knapsack.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dynamic_programming/{Unbounded_0_1_Knapsack.cpp => unbounded_0_1_knapsack.cpp} (100%) diff --git a/dynamic_programming/Unbounded_0_1_Knapsack.cpp b/dynamic_programming/unbounded_0_1_knapsack.cpp similarity index 100% rename from dynamic_programming/Unbounded_0_1_Knapsack.cpp rename to dynamic_programming/unbounded_0_1_knapsack.cpp From c9e9d3b63580dba789b395372f014cffd82470b5 Mon Sep 17 00:00:00 2001 From: realstealthninja <68815218+realstealthninja@users.noreply.github.com> Date: Thu, 7 Nov 2024 05:44:11 +0530 Subject: [PATCH 17/18] chore: remove spaces --- dynamic_programming/unbounded_0_1_knapsack.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dynamic_programming/unbounded_0_1_knapsack.cpp b/dynamic_programming/unbounded_0_1_knapsack.cpp index 5d984cc890e..ec07d594f47 100644 --- a/dynamic_programming/unbounded_0_1_knapsack.cpp +++ b/dynamic_programming/unbounded_0_1_knapsack.cpp @@ -30,7 +30,6 @@ #include // Standard input-output stream #include // Standard library for using dynamic arrays (vectors) - /** * @namespace dynamic_programming * @brief Namespace for dynamic programming algorithms From 0dbd473883223c942332d5f15371e4d55192bdeb Mon Sep 17 00:00:00 2001 From: realstealthninja <68815218+realstealthninja@users.noreply.github.com> Date: Thu, 7 Nov 2024 05:44:18 +0530 Subject: [PATCH 18/18] Update dynamic_programming/unbounded_0_1_knapsack.cpp --- dynamic_programming/unbounded_0_1_knapsack.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dynamic_programming/unbounded_0_1_knapsack.cpp b/dynamic_programming/unbounded_0_1_knapsack.cpp index ec07d594f47..384ea997884 100644 --- a/dynamic_programming/unbounded_0_1_knapsack.cpp +++ b/dynamic_programming/unbounded_0_1_knapsack.cpp @@ -24,7 +24,6 @@ * @see dynamic_programming/0_1_knapsack.cpp */ - #include // For using assert function to validate test cases #include // For fixed-width integer types like std::uint16_t #include // Standard input-output stream