After implementing suggestions from my previous questions about SJF, priority and round robin.
Here I have scheduling.h
which contains a struct Data
and virtual
member functions. Then I have derived class for each scheduling algorithm. Only calcEndTime()
is defined for each scheduling algorithm. I have asked to enter priority in each algortihm because it must be in Data
so it is bounded to arrivalTime
and burstTime
. This is first time I have written program related to inheritance. Suggest me improvements.
scheduling.h
#ifndef SCHEDULING_H_
#define SCHEDULING_H_
#include <vector>
class Scheduler
{
public:
double avgWaitingTime;
double avgTurnAroundTime;
struct Data
{
unsigned arrivalTime;
//When process start to execute
unsigned burstTime;
//only for priority Scheduling
unsigned priority;
Data(unsigned arrivalTime, unsigned burstTime, unsigned priority):
arrivalTime(std::move(arrivalTime)),
burstTime(std::move(burstTime)),
priority(std::move(priority))
{}
Data() = default;
};
std::vector<Data> data;
//process wait to execute after they have arrived
std::vector<unsigned> waitingTime;
//total time taken by processes
std::vector<unsigned> turnAroundTime;
//time when a process end
std::vector<unsigned> endTime;
Scheduler(unsigned num = 0);
Scheduler(const Scheduler&) = delete;
Scheduler &operator=(const Scheduler&) = delete;
Scheduler(Scheduler&&) = delete;
Scheduler &operator=(Scheduler&&) = delete;
~Scheduler() = default;
void calcWaitingTime();
void calcTurnAroundTime();
virtual void calcEndTime() = 0;
void printInfo() const;
};
#endif
scheduling.cpp
#include <iostream>
#include <vector>
#include "scheduling.h"
Scheduler::Scheduler(unsigned num): endTime(num, 0)
{
unsigned arrivalVal, burstVal, priorityVal;
data.reserve(num);
endTime.reserve(num);
waitingTime.reserve(num);
turnAroundTime.reserve(num);
std::cout << "\nEnter arrival time and burst time and priority eg(5 18 2)\n";
std::cout << "If it is not priority scheduling enter 0 for priority\n";
std::cout << "Lower integer has higher priority\n";
for (unsigned i = 0; i < num; i++)
{
std::cout << "\nProcess" << i+1 << ": ";
std::cin >> arrivalVal >> burstVal >> priorityVal;
data.push_back( Data(arrivalVal, burstVal, priorityVal) );
}
}
void Scheduler::calcTurnAroundTime()
{
double sum = 0.00;
for (std::size_t i = 0; i < data.size(); i++)
{
unsigned val = endTime[i] - data[i].arrivalTime;
turnAroundTime.push_back(val);
sum += (double)val;
}
avgTurnAroundTime = sum / turnAroundTime.size();
}
void Scheduler::calcWaitingTime()
{
double sum = 0.00;
for (std::size_t i = 0; i < data.size(); i++)
{
unsigned val = turnAroundTime[i] - data[i].burstTime;
waitingTime.push_back(val);
sum += (double)val;
}
avgWaitingTime = sum / waitingTime.size();
}
void Scheduler::printInfo() const
{
std::cout << "ProcessID\tArrival Time\tBurst Time\tPriority\tEnd Time\tWaiting Time";
std::cout << "\tTurnaround Time\n";
for (std::size_t i = 0; i < data.size(); i++)
{
std::cout << i+1 << "\t\t" << data[i].arrivalTime << "\t\t";
std::cout << data[i].burstTime << "\t\t" <<data[i].priority << "\t\t";
std::cout << endTime[i] << "\t\t";
std::cout << waitingTime[i] <<"\t\t" << turnAroundTime[i] <<'\n';
}
std::cout << "Average Waiting Time : " << avgWaitingTime << '\n';
std::cout << "Average Turn Around Time : " << avgTurnAroundTime << '\n';
}
shortestjobfirst.h
#ifndef SHORTESTJOBFIRST_H_
#define SHORTESTJOBFIRST_H_
#include "scheduling.h"
class ShortestJobFirst : public Scheduler
{
public:
ShortestJobFirst(unsigned num);
ShortestJobFirst() = default;
ShortestJobFirst(const ShortestJobFirst&) = delete;
ShortestJobFirst &operator=(const ShortestJobFirst&) = delete;
ShortestJobFirst(ShortestJobFirst&&) = delete;
ShortestJobFirst &operator=(ShortestJobFirst&&) = delete;
~ShortestJobFirst() = default;
void calcEndTime();
};
#endif
shortestjobfirst.cpp
#include <iostream>
#include <array>
#include <vector>
#include <algorithm> // std::find
#include <iterator> // std::begin, std::end
#include <limits> //std::numeric_limits
#include "scheduling.h"
#include "shortestjobfirst.h"
ShortestJobFirst::ShortestJobFirst(unsigned num) :Scheduler(num)
{}
void ShortestJobFirst::calcEndTime()
{
//If arrival time is not sorted
//sort burst time according to arrival time
static const auto byArrival = [](const Data &a, const Data &b)
{
return a.arrivalTime < b.arrivalTime;
};
std::sort(data.begin(), data.end(), byArrival);
//copy values of burst time in new vector
std::vector<unsigned> burstTimeCopy;
for (auto it = data.begin(); it != data.end(); ++it)
{
unsigned val = (*it).burstTime;
burstTimeCopy.push_back(val);
}
unsigned timeCounter = 0;
unsigned currActiveProcessID = 0;
while (!(std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(),
[] (unsigned e) { return e == 0; })))
{
std::size_t dataSize = data.size();
//All processes are not arrived
if (timeCounter <= data[dataSize -1].arrivalTime)
{
unsigned minBurstTime = std::numeric_limits<uint>::max();
//Find index with minimum burst Time remaining
for (std::size_t i = 0; i < burstTimeCopy.size(); i++)
{
if (burstTimeCopy[i] != 0 && burstTimeCopy[i] < minBurstTime
&& data[i].arrivalTime <= timeCounter)
{
minBurstTime = burstTimeCopy[i];
currActiveProcessID = i;
}
}
burstTimeCopy[currActiveProcessID] -= 1;
timeCounter++;
if (burstTimeCopy[currActiveProcessID] == 0)
{
endTime[currActiveProcessID] = timeCounter;
}
}
else //When all processes are arrived
{
unsigned minBurstTime = std::numeric_limits<uint>::max();
//Find index with minimum burst Time remaining
for (std::size_t i = 0; i < burstTimeCopy.size(); i++)
{
if (burstTimeCopy[i] != 0 && burstTimeCopy[i] < minBurstTime)
{
minBurstTime = burstTimeCopy[i];
currActiveProcessID = i;
}
}
timeCounter += minBurstTime;
endTime[currActiveProcessID] = timeCounter;
burstTimeCopy[currActiveProcessID] = 0;
}
}
}
int main()
{
int num;
std::cout << "Enter the number of processes\n";
std::cin >> num;
ShortestJobFirst batch(num);
batch.calcEndTime();
batch.calcTurnAroundTime();
batch.calcWaitingTime();
batch.printInfo();
}
Priority
, ShortestJobFirst
are nearly smae and in RoundRobin
we have member function timeQuantum
which is entered through constructor.
priorit.cpp
#include <iostream>
#include <vector>
#include <algorithm> // std::find
#include <iterator> // std::begin, std::end
#include <limits> //std::numeric_limits
#include "scheduling.h"
#include "priority.h"
Priority::Priority(unsigned num): Scheduler(num)
{}
void Priority::calcEndTime()
{
//If arrival time is not sorted
//sort burst time according to arrival time
static const auto byArrival = [](const Data &a, const Data &b)
{
return a.arrivalTime < b.arrivalTime;
};
std::sort(data.begin(), data.end(), byArrival);
//copy values of burst time in new vector
std::vector<unsigned> burstTimeCopy;
for (auto it = data.begin(); it != data.end(); ++it)
{
unsigned val = (*it).burstTime;
burstTimeCopy.push_back(val);
}
unsigned timeCounter = 0;
unsigned currActiveProcessID = 0;
while (!(std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(),
[] (unsigned e) { return e == 0; })))
{
std::size_t dataSize = data.size();
//All processes are not arrived
if (timeCounter <= data[dataSize - 1].arrivalTime)
{
unsigned maxPriority = std::numeric_limits<uint>::max();
for (std::size_t i = 0; i < burstTimeCopy.size(); i++)
{
if (burstTimeCopy[i] != 0 && data[i].priority < maxPriority
&& data[i].arrivalTime <= timeCounter)
{
maxPriority = data[i].priority;
currActiveProcessID = i;
}
}
burstTimeCopy[currActiveProcessID] -= 1;
timeCounter++;
if (burstTimeCopy[currActiveProcessID] == 0)
{
endTime[currActiveProcessID] = timeCounter;
}
}
else //When all processes are arrived
{
unsigned maxPriority = std::numeric_limits<uint>::max();
for (std::size_t i = 0 ; i < burstTimeCopy.size(); i++)
{
if (burstTimeCopy[i] != 0 && data[i].priority < maxPriority)
{
maxPriority = data[i].priority;
currActiveProcessID = i;
}
}
timeCounter += burstTimeCopy[currActiveProcessID];
burstTimeCopy[currActiveProcessID] = 0;
endTime[currActiveProcessID] = timeCounter;
}
}
}
int main()
{
int num;
std::cout << "Enter the number of processes\n";
std::cin >> num;
Priority prioritySchedule(num);
prioritySchedule.calcEndTime();
prioritySchedule.calcTurnAroundTime();
prioritySchedule.calcWaitingTime();
prioritySchedule.printInfo();
}
roundrobin.cpp
#include <iostream>
#include <vector>
#include <algorithm> // std::find
#include <iterator> // std::begin, std::end
#include <limits> //std::numeric_limits
#include "scheduling.h"
#include "roundrobin.h"
RoundRobin::RoundRobin(unsigned num, unsigned quantum): Scheduler(num)
{
timeQuantum = quantum;
}
void RoundRobin::calcEndTime()
{
//If arrival time is not sorted
//sort burst time according to arrival time
static const auto byArrival = [](const Data &a, const Data &b)
{
return a.arrivalTime < b.arrivalTime;
};
std::sort(data.begin(), data.end(), byArrival);
//copy values of burst time in new vector
std::vector<unsigned> burstTimeCopy;
for (auto it = data.begin(); it != data.end(); ++it)
{
unsigned val = (*it).burstTime;
burstTimeCopy.push_back(val);
}
unsigned timeCounter = 0;
while (!(std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(),
[] (unsigned e) { return e == 0; })))
{
unsigned currActiveProcessID = 0;
auto it = burstTimeCopy.begin();
while (it != burstTimeCopy.end())
{
if (burstTimeCopy[currActiveProcessID] > timeQuantum)
{
burstTimeCopy[currActiveProcessID] -= timeQuantum;
timeCounter += timeQuantum;
}
else if (burstTimeCopy[currActiveProcessID] > 0)
{
timeCounter += burstTimeCopy[currActiveProcessID];
burstTimeCopy[currActiveProcessID] = 0;
endTime[currActiveProcessID] = timeCounter;
}
currActiveProcessID++;
it++;
}
}
}
int main()
{
unsigned num, timeQuantum;
std::cout << "Enter number of process: ";
std::cin >> num;
std::cout << "\nEnter time quantum : ";
std::cin >> timeQuantum;
RoundRobin roundRobin(num, timeQuantum);
roundRobin.calcEndTime();
roundRobin.calcTurnAroundTime();
roundRobin.calcWaitingTime();
roundRobin.printInfo();
}