5
\$\begingroup\$

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();
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

At first glance, in Scheduler, I would replace

std::vector<Data> data;
std::vector<unsigned> waitingTime;
std::vector<unsigned> turnAroundTime;
std::vector<unsigned> endTime;

by

struct Process {
    Data data;
    unsigned waitingTime, turnAroundTime, endTime;        
};
std::vector<Process> processes;

or put the members waitingTime turnAroundTime endTime in Data directly

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.