From 122f5e5556fa33853d8c73a4aecc1e0f3cda53ca Mon Sep 17 00:00:00 2001 From: "Md. Asif Joardar" Date: Wed, 10 May 2023 19:04:55 +0600 Subject: [PATCH] Add Round Robin scheduling (#4184) --- .../scheduling/RRScheduling.java | 99 +++++++++++++++++++ .../scheduling/RRSchedulingTest.java | 65 ++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/main/java/com/thealgorithms/scheduling/RRScheduling.java create mode 100644 src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java diff --git a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java new file mode 100644 index 00000000..6d26bfd7 --- /dev/null +++ b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java @@ -0,0 +1,99 @@ +/** + * @author Md Asif Joardar + */ + +package com.thealgorithms.scheduling; + +import com.thealgorithms.devutils.entities.ProcessDetails; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * The Round-robin scheduling algorithm is a kind of preemptive First come, First Serve CPU Scheduling algorithm. + * This can be understood here - https://www.scaler.com/topics/round-robin-scheduling-in-os/ + */ + +public class RRScheduling { + private List processes; + private int quantumTime; + + RRScheduling(final List processes, int quantumTime) { + this.processes = processes; + this.quantumTime = quantumTime; + } + + public void scheduleProcesses() { + evaluateTurnAroundTime(); + evaluateWaitingTime(); + } + + private void evaluateTurnAroundTime() { + int processesNumber = processes.size(); + + if(processesNumber == 0) { + return; + } + + Queue queue = new LinkedList<>(); + queue.add(0); + int currentTime = 0; // keep track of the time + int completed = 0; + int[] mark = new int[processesNumber]; + Arrays.fill(mark, 0); + mark[0] = 1; + + // a copy of burst time to store the remaining burst time + int[] remainingBurstTime = new int[processesNumber]; + for (int i = 0; i < processesNumber; i++) { + remainingBurstTime[i] = processes.get(i).getBurstTime(); + } + + while (completed != processesNumber){ + int index = queue.poll(); + + if(remainingBurstTime[index] == processes.get(index).getBurstTime()){ + currentTime = Math.max(currentTime, processes.get(index).getArrivalTime()); + } + + if(remainingBurstTime[index] - quantumTime > 0){ + remainingBurstTime[index] -= quantumTime; + currentTime += quantumTime; + } else { + currentTime += remainingBurstTime[index]; + processes.get(index).setTurnAroundTimeTime(currentTime - processes.get(index).getArrivalTime()); + completed++; + remainingBurstTime[index]=0; + } + + // If some process has arrived when this process was executing, insert them into the queue. + for (int i=1; i < processesNumber; i++){ + if(remainingBurstTime[i] > 0 && processes.get(i).getArrivalTime() <= currentTime && mark[i] == 0){ + mark[i]=1; + queue.add(i); + } + } + + // If the current process has burst time remaining, push the process into the queue again. + if(remainingBurstTime[index] > 0) queue.add(index); + + // If the queue is empty, pick the first process from the list that is not completed. + if(queue.isEmpty()){ + for (int i=1; i 0){ + mark[i] = 1; + queue.add(i); + break; + } + } + } + } + } + + private void evaluateWaitingTime() { + for (int i = 0; i < processes.size(); i++) + processes.get(i).setWaitingTime(processes.get(i).getTurnAroundTimeTime() - processes.get(i).getBurstTime()); + } +} diff --git a/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java new file mode 100644 index 00000000..935ff733 --- /dev/null +++ b/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java @@ -0,0 +1,65 @@ +package com.thealgorithms.scheduling; + +import static org.junit.jupiter.api.Assertions.*; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +class RRSchedulingTest { + @Test + public void testingProcesses() { + List processes = addProcessesForRR(); + final RRScheduling rrScheduling = new RRScheduling(processes, 4); // for sending to RR with quantum value 4 + + rrScheduling.scheduleProcesses(); + + assertEquals(6, processes.size()); + + assertEquals("P1", processes.get(0).getProcessId()); + assertEquals(12, processes.get(0).getWaitingTime()); + assertEquals(17, processes.get(0).getTurnAroundTimeTime()); + + assertEquals("P2", processes.get(1).getProcessId()); + assertEquals(16, processes.get(1).getWaitingTime()); + assertEquals(22, processes.get(1).getTurnAroundTimeTime()); + + assertEquals("P3", processes.get(2).getProcessId()); + assertEquals(6, processes.get(2).getWaitingTime()); + assertEquals(9, processes.get(2).getTurnAroundTimeTime()); + + assertEquals("P4", processes.get(3).getProcessId()); + assertEquals(8, processes.get(3).getWaitingTime()); + assertEquals(9, processes.get(3).getTurnAroundTimeTime()); + + assertEquals("P5", processes.get(4).getProcessId()); + assertEquals(15, processes.get(4).getWaitingTime()); + assertEquals(20, processes.get(4).getTurnAroundTimeTime()); + + assertEquals("P6", processes.get(5).getProcessId()); + assertEquals(11, processes.get(5).getWaitingTime()); + assertEquals(15, processes.get(5).getTurnAroundTimeTime()); + + } + + private List addProcessesForRR() { + final ProcessDetails process1 = new ProcessDetails("P1", 0, 5); + final ProcessDetails process2 = new ProcessDetails("P2", 1, 6); + final ProcessDetails process3 = new ProcessDetails("P3", 2, 3); + final ProcessDetails process4 = new ProcessDetails("P4", 3, 1); + final ProcessDetails process5 = new ProcessDetails("P5", 4, 5); + final ProcessDetails process6 = new ProcessDetails("P6", 6, 4); + + final List processDetails = new ArrayList<>(); + processDetails.add(process1); + processDetails.add(process2); + processDetails.add(process3); + processDetails.add(process4); + processDetails.add(process5); + processDetails.add(process6); + + return processDetails; + } +} \ No newline at end of file