#include <bits/stdc++.h>
using namespace std;
struct Node {
int id;
int arrivalTime;
int burstTime;
int turnaroundTime;
int waitingTime;
int completionTime;
Node* next;
};
class CircularQueue {
private:
Node* front;
Node* rear;
public:
CircularQueue() : front(nullptr), rear(nullptr) {}
bool isEmpty() {
return front == nullptr;
}
void enqueue(int id, int arrivalTime, int burstTime) {
Node* newNode = new Node{id, arrivalTime, burstTime, 0, 0, 0, nullptr};
if (isEmpty()) {
front = rear = newNode;
rear->next = front; // Point to itself
} else {
rear->next = newNode; // Link the new node
rear = newNode; // Update rear
rear->next = front; // Make it circular
}
}
void dequeue() {
if (isEmpty()) {
cout << "queue is empty" << endl;
return;
}
Node* temp = front;
if (front == rear) {
front = rear = nullptr;
} else {
front = front->next; // Move front to the next node
rear->next = front; // Maintain circular link
}
delete temp;
}
void display() {
if (isEmpty()) {
cout << "queue is empty" << endl;
return;
}
Node* temp = front;
do {
cout << temp->id << "\t\t" << temp->arrivalTime << "\t\t" << temp->burstTime << "\t\t" << temp->completionTime << "\t\t\t" << temp->turnaroundTime << "\t\t\t" << temp->waitingTime << endl;
temp = temp->next;
} while (temp != front);
}
Node* getFront() {
return front;
}
};
class RoundRobinScheduler {
private:
int timeQuantum, ids;
void sortArrivalTime();
bool isPending(map<int, int>& burstTimes);
bool isAlone(map<int, int>& burstTimes);
public:
RoundRobinScheduler(int tq) : timeQuantum(tq), ids(0) {};
CircularQueue queue;
void inputTime();
void displayTime();
void calculateTime();
};
void RoundRobinScheduler::inputTime() {
int id = ++ids ; // Assign ID based on current queue
cout << "\nenter for process-" << id << endl;
int arrivalTime, burstTime;
cout << "arrival-time: ";
cin >> arrivalTime;
cout << "burst-time: ";
cin >> burstTime;
queue.enqueue(id, arrivalTime, burstTime);
}
void RoundRobinScheduler::displayTime() {
cout << "\n\nround robin scheduling:" << endl;
cout << "process-id\tarrival-time\tburst-time\tcompletion-time\t\tturnaround-time\t\twaiting-time" << endl;
queue.display();
}
void RoundRobinScheduler::sortArrivalTime() {
}
bool RoundRobinScheduler::isPending(map<int, int>& burstTimes) {
for (auto& it : burstTimes) {
if (it.second != 0) return true;
}
return false;
}
bool RoundRobinScheduler::isAlone(map<int, int>& burstTimes) {
int count = 0;
for (auto& it : burstTimes) {
if (it.second != 0) count++;
}
return (count == 1) ? true : false;
}
void RoundRobinScheduler::calculateTime() {
sortArrivalTime();
Node* current = queue.getFront();
// storing burstTimes
map<int, int> burstTimes;
do {
burstTimes[current->id] = current->burstTime;
current = current->next;
} while(current != queue.getFront());
// jobs scheduling
cout << "\njobs:\t";
current = queue.getFront();
int timePassed = 0;
while (isPending(burstTimes)) {
if (burstTimes[current->id] == 0) {
current=current->next;
continue;
}
else if ((isAlone(burstTimes)) || (burstTimes[current->id] <= timeQuantum)) {
timePassed += burstTimes[current->id];
burstTimes[current->id] = 0;
current->completionTime = timePassed;
}
else {
burstTimes[current->id] -= timeQuantum;
timePassed += timeQuantum;
}
cout << current->id << "\t";
current = current->next;
}
// calculating other fields - turnaround and waiting time
current = queue.getFront();
do {
current->turnaroundTime = current->completionTime - current->arrivalTime;
current->waitingTime = current->turnaroundTime - current->burstTime;
current = current->next;
} while (current != queue.getFront());
}
int main() {
int tq;
cout << "\nenter time quantum: ";
cin >> tq;
RoundRobinScheduler obj(tq);
int n;
cout << "\nenter number of processes: ";
cin >> n;
for (int i = 0; i < n; i++) {
obj.inputTime();
}
obj.calculateTime();
obj.displayTime();
return 0;
}