diff --git a/src/Global.java b/src/Global.java index 2813be5fc6818ce1e73393bec6d5e5d7481017be..67914363ce901da998be38f283b35c01f95b344b 100644 --- a/src/Global.java +++ b/src/Global.java @@ -4,28 +4,36 @@ */ public class Global { - private SRTF srtf = new SRTF(); //high priority scheduler - private RR rr = new RR(); //low priority scheduler + private SRTF srtf = new SRTF(this); //high priority scheduler + private RR rr = new RR(this); //low priority scheduler String history = ""; //a string with tha names of task that have taken control so far - I will use this only for the output public void add(Task t) { - if (t.isKernel) + Main.schedulersEmpty=false; + + if (t.isKernel) { srtf.add(t); - else + rr.stop(); + } else { rr.add(t); + } } public void tick() { + if(srtf.isEmpty() && rr.isEmpty()) {Main.schedulersEmpty = true; return;} + srtf.tick(); + rr.tick(); + if (srtf.isEmpty()) rr.start(); } /** - * A task is forcibly taking control + * A task is taking control * @param t the task to be run */ public void changeRunning(Task t) { - + history += t.name; } } diff --git a/src/Main.java b/src/Main.java index 1ce56a9a96ce6e02c88eee0fb49136232e52c657..b1e2db716d959fafedee8ca31e85fd3e5f5f5b9e 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,7 +1,77 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.LinkedList; + public class Main { + private static LinkedList<Task> tasks = new LinkedList<>(); //stores all the tasks in ascending order regarding start times + private static LinkedList<Task> runningTasks = new LinkedList<>(); //stores a backup pointer of all task because we delete them from tasks when giving to the scheduler; used only for determining waiting times + static boolean schedulersEmpty = true; //signals if the schedulers emptied out + + private static Global scheduler = new Global(); + public static void main(String[] args) { - System.out.println("Hello world!"); + + //reading input + //------------- + + BufferedReader sysIn = new BufferedReader(new InputStreamReader(System.in)); + + String currentLine; + try { + + currentLine = sysIn.readLine(); + while (!(currentLine==null) && !currentLine.equals("")) { + String[] lineContent = currentLine.split(","); + Task readTask = new Task(lineContent[0].charAt(0), lineContent[1].equals("0"), Integer.parseInt(lineContent[2]), Integer.parseInt(lineContent[3])); + + //inserting read task to tasks + if (tasks.size() == 0) {tasks.add(readTask);} + else { + int i=0; + while(tasks.size() <= i && tasks.get(i).startTime < readTask.startTime) i++; + tasks.add(i, readTask); + } + + currentLine = sysIn.readLine(); + } + + } catch (IOException e) { + e.printStackTrace(); + } + + //running simulation + //------------------ + + //special case: no tasks + if(tasks.size()==0) {System.out.println("\n\n"); return;} + + for(int now = 0; tasks.size()>0 || !schedulersEmpty; now++) { + //adding incoming tasks + for(int i=0; i<tasks.size(); i++) { + if(tasks.get(i).startTime == now) { + scheduler.add(tasks.get(i)); + runningTasks.add(tasks.get(i)); + tasks.remove(i); + } + } + + //ticking + scheduler.tick(); + } + + + + //writing output + //-------------- + System.out.println(scheduler.history); + + System.out.print(runningTasks.get(0).name + ":" + runningTasks.get(0).getWaitingTime()); + for(int i = 1; i< runningTasks.size(); i++) { + System.out.print("," + runningTasks.get(i).name + ":" + runningTasks.get(i).getWaitingTime()); + } + } } diff --git a/src/RR.java b/src/RR.java index 0e21b5aead2b67e085f550732e226383619ec2ca..ea965d3120333c69d3efdfb049b1717df3230e96 100644 --- a/src/RR.java +++ b/src/RR.java @@ -1,4 +1,4 @@ -import java.util.PriorityQueue; +import java.util.ArrayDeque; import java.util.Queue; /** @@ -6,18 +6,29 @@ import java.util.Queue; */ public class RR { + private final Global global; + private static final int timeSlice = 2; //time in ticks while a task is allowed to run private int runningFor = 0; //the number of timeslices the active task has been running for - private Queue<Task> waitingQueue = new PriorityQueue<>(); //inactive tasks - private Task activeTask; //the active task; null if there are none + private boolean enabled = true; - public void start() { + private Queue<Task> waitingQueue = new ArrayDeque<>(); //inactive tasks + private Task activeTask = null; //the active task; null if there are none + public RR(Global global) { + this.global = global; } - public void stop() { + public void start() { + enabled = true; + } + public void stop() { + enabled = false; + runningFor = 0; + if(activeTask!=null) waitingQueue.add(activeTask); + activeTask = null; } public void add(Task t) { @@ -28,7 +39,38 @@ public class RR { * signals a processor tick */ public void tick() { + if(!enabled) { + //System.out.println("Running RR: " + ((activeTask == null) ? "null" : activeTask.name)); + for(Task t : waitingQueue) t.waitOne(); + return; + } + + runningFor++; + + //swapping + if(waitingQueue.size() > 0 && (runningFor == timeSlice || activeTask == null)) { //we swap if we can and if we need to; we need to when the running period is over or the current task is not running anymore + + if (activeTask != null) waitingQueue.add(activeTask); + activeTask = waitingQueue.remove(); + + global.changeRunning(activeTask); + + runningFor = 0; + } + + //System.out.println("Running RR: " + ((activeTask == null) ? "null" : activeTask.name)); + + //registering time flow + for(Task t : waitingQueue) t.waitOne(); + if(activeTask!=null) { + activeTask.runOne(); + if(activeTask.remainingTime == 0) activeTask = null; + } + + } + public boolean isEmpty() { + return activeTask==null && waitingQueue.size()==0; } } diff --git a/src/SRTF.java b/src/SRTF.java index 925c509251fa0057b953ef36d36f9f3eb11c3ded..6d0d01d9e027ab161511ab23d61252331d5d93f1 100644 --- a/src/SRTF.java +++ b/src/SRTF.java @@ -1,23 +1,62 @@ -import java.util.PriorityQueue; -import java.util.Queue; +import java.util.LinkedList; /** * An SRTF (shortest remaining time first) scheduler designed for high priority tasks */ public class SRTF { - private Queue<Task> waitingQueue = new PriorityQueue<>(); //inactive tasks - private Task activeTask; //active task; null if there are none + private final Global global; + + private LinkedList<Task> waitingQueue = new LinkedList<>(); //inactive tasks + private Task activeTask = null; //active task; null if there are none + + private boolean needSwap = true; //stores if the active task should be changed + + public SRTF(Global global) { + this.global = global; + } public void add(Task t) { waitingQueue.add(t); + + if(activeTask == null || t.remainingTime < activeTask.remainingTime) needSwap = true; } /** * signals a processor tick */ public void tick() { - + if (isEmpty()) return; + + //swapping if necessary + if (needSwap) { + int minIndex = -1; int minValue = Integer.MAX_VALUE; + for(int i=0; i<waitingQueue.size(); i++) { + if (waitingQueue.get(i).remainingTime < minValue) {minValue = waitingQueue.get(i).remainingTime; minIndex = i;} + } + + Task temp = activeTask; + activeTask = waitingQueue.get(minIndex); + waitingQueue.remove(minIndex); + if(temp != null) waitingQueue.add(temp); + + global.changeRunning(activeTask); + + needSwap = false; + } + + //System.out.print("SRTF interrupt: " + activeTask.name + " "); + + //registering time flowing + for(Task t : waitingQueue) t.waitOne(); + activeTask.runOne(); + if(activeTask.remainingTime == 0) { + needSwap = true; + activeTask = null; + } } + public boolean isEmpty() { + return activeTask==null && waitingQueue.size()==0; + } }