diff --git a/src/main/java/mvd/jester/App.java b/src/main/java/mvd/jester/App.java index 8c73eff..48fc1d6 100644 --- a/src/main/java/mvd/jester/App.java +++ b/src/main/java/mvd/jester/App.java @@ -1,6 +1,8 @@ package mvd.jester; +import java.io.PrintWriter; import mvd.jester.model.SystemSetup; +import mvd.jester.simulator.EventPrinter; import mvd.jester.simulator.MaiaBertogna; import mvd.jester.simulator.SchmidMottok; @@ -10,43 +12,54 @@ import mvd.jester.simulator.SchmidMottok; */ public class App { public static void main(String[] args) { - // SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); - // TestEnvironment te = new TestEnvironment(builder, 400); + SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); + TestEnvironment te = new TestEnvironment(builder, 40000); + + te.registerTestPair(mvd.jester.tests.MaiaBertogna.class, + mvd.jester.simulator.MaiaBertogna.class); - // te.registerTestPair(mvd.jester.tests.MaiaBertogna.class, - // mvd.jester.simulator.MaiaBertogna.class); + te.registerTestPair(mvd.jester.tests.SchmidMottok.class, + mvd.jester.simulator.SchmidMottok.class); - // te.registerTestPair(mvd.jester.tests.SchmidMottok.class, - // mvd.jester.simulator.SchmidMottok.class); + te.runTests(); - // te.runTests(); + // boolean mbWorked = false; + // boolean smWorked = false; - boolean mbWorked = false; - boolean smWorked = false; + // SystemSetup thisOne = null; + // EventPrinter.enablePrinter(); - SystemSetup thisOne = null; + // do { + // SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); + // SystemSetup systemSetup = builder.build(); - do { - SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); - SystemSetup systemSetup = builder.build(); + // SchmidMottok sm = new SchmidMottok(systemSetup); + // MaiaBertogna mb = new MaiaBertogna(systemSetup); - SchmidMottok sm = new SchmidMottok(systemSetup); - MaiaBertogna mb = new MaiaBertogna(systemSetup); + // smWorked = sm.runSimulation(); + // mbWorked = mb.runSimulation(); - smWorked = sm.runSimulation(); - mbWorked = mb.runSimulation(); + // thisOne = systemSetup; + // } while (smWorked == mbWorked); - thisOne = systemSetup; - } while (smWorked == mbWorked); + // try (PrintWriter out = new PrintWriter("./results/manCheck.txt")) { + // out.println(thisOne); + // } catch (Exception e) { + // System.out.println("Ähm something went horribly wrong!"); + // } + // SchmidMottok sm = new SchmidMottok(thisOne); + // MaiaBertogna mb = new MaiaBertogna(thisOne); - SchmidMottok sm = new SchmidMottok(thisOne); - MaiaBertogna mb = new MaiaBertogna(thisOne); + // mb.runSimulation(); + // sm.runSimulation(); - mb.runSimulation(); - sm.runSimulation(); + // SystemSetup systemSetup = SystemSetup.fromFile("results/manCheck.txt"); + // EventPrinter.enablePrinter(); + // SchmidMottok sm = new SchmidMottok(systemSetup); + // sm.runSimulation(); } } diff --git a/src/main/java/mvd/jester/model/Segment.java b/src/main/java/mvd/jester/model/Segment.java index 8c45b89..548599c 100644 --- a/src/main/java/mvd/jester/model/Segment.java +++ b/src/main/java/mvd/jester/model/Segment.java @@ -1,5 +1,7 @@ package mvd.jester.model; +import com.google.common.math.LongMath; + // import com.google.common.math.LongMath; public class Segment { @@ -15,14 +17,17 @@ public class Segment { if (numberOfJobs == 1) { this.taskletWcet = this.jobWcet; this.numberOfTasklets = this.numberOfJobs; + } else if (this.numberOfJobs > this.jobWcet) { + this.taskletWcet = LongMath.gcd(jobWcet, numberOfJobs); + this.numberOfTasklets = this.jobWcet * this.numberOfJobs / this.taskletWcet; } else { - // this.taskletWcet = LongMath.gcd(jobWcet, numberOfJobs); - // this.numberOfTasklets = this.jobWcet * this.numberOfJobs / this.taskletWcet; this.taskletWcet = numberOfJobs; this.numberOfTasklets = jobWcet; } } + + /** * @return the numberOfJobs */ diff --git a/src/main/java/mvd/jester/priority/EarliestDeadineFirst.java b/src/main/java/mvd/jester/priority/EarliestDeadineFirst.java new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/main/java/mvd/jester/priority/EarliestDeadineFirst.java diff --git a/src/main/java/mvd/jester/simulator/AbstractSimulator.java b/src/main/java/mvd/jester/simulator/AbstractSimulator.java index 9e874a2..d64907e 100644 --- a/src/main/java/mvd/jester/simulator/AbstractSimulator.java +++ b/src/main/java/mvd/jester/simulator/AbstractSimulator.java @@ -1,5 +1,6 @@ package mvd.jester.simulator; +import java.util.Comparator; import java.util.HashSet; import java.util.Optional; import java.util.Set; @@ -42,11 +43,8 @@ public abstract class AbstractSimulator implements SimulatorInterface { return false; } - Set sortedProcessors = - new TreeSet<>((p1, p2) -> (int) (!p1.getJob().isPresent() ? -1 - : !p2.getJob().isPresent() ? 1 : -1)); + Set sortedProcessors = sortProcessors(processors); - processors.forEach(p -> sortedProcessors.add(p)); for (ProcessorContext p : sortedProcessors) { for (TaskContextInterface tc : readyTasks) { if (p.acceptTask(tc, t)) { @@ -61,6 +59,7 @@ public abstract class AbstractSimulator implements SimulatorInterface { if (optionalTc.isPresent()) { TaskContextInterface tc = optionalTc.get(); if (t >= tc.getDeadline()) { + EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!"); return false; } readyTasks.remove(optionalTc.get()); @@ -79,6 +78,34 @@ public abstract class AbstractSimulator implements SimulatorInterface { this.hyperPeriod = systemSetup.getTasks().last().getPeriod() * 2; } + private Set sortProcessors(Set processors) { + Set sortedProcessors = new TreeSet<>(new ProcessorComparator()); + processors.forEach(p -> sortedProcessors.add(p)); + + return sortedProcessors; + } + + private class ProcessorComparator implements Comparator { + + @Override + public int compare(ProcessorContext p1, ProcessorContext p2) { + if (!p1.getJob().isPresent()) { + return -1; + } else if (!p2.getJob().isPresent()) { + return 1; + } else { + long p1Period = p1.getJob().get().getTaskContext().getTask().getPeriod(); + long p2Period = p2.getJob().get().getTaskContext().getTask().getPeriod(); + if (p1Period == p2Period) { + return 1; + } else { + return (int) (p2.getJob().get().getTaskContext().getTask().getPeriod() + - p1.getJob().get().getTaskContext().getTask().getPeriod()); + } + } + } + + } } diff --git a/src/main/java/mvd/jester/simulator/EventPrinter.java b/src/main/java/mvd/jester/simulator/EventPrinter.java new file mode 100644 index 0000000..e4ac56d --- /dev/null +++ b/src/main/java/mvd/jester/simulator/EventPrinter.java @@ -0,0 +1,28 @@ +package mvd.jester.simulator; + +/** + * EventPrinter + */ +public class EventPrinter { + + private static boolean printerEnabled; + + private EventPrinter() { + printerEnabled = false; + } + + public static void enablePrinter() { + printerEnabled = true; + } + + public static void disablePrinter() { + printerEnabled = false; + } + + public static void print(String text) { + if (printerEnabled) { + System.out.println(text); + } + } + +} diff --git a/src/main/java/mvd/jester/simulator/MaiaBertogna.java b/src/main/java/mvd/jester/simulator/MaiaBertogna.java index cd0f096..f21fa4a 100644 --- a/src/main/java/mvd/jester/simulator/MaiaBertogna.java +++ b/src/main/java/mvd/jester/simulator/MaiaBertogna.java @@ -17,9 +17,13 @@ public class MaiaBertogna extends AbstractSimulator { protected boolean releaseTasks(long timeStep) { for (Task t : systemSetup.getTasks()) { if (timeStep % t.getPeriod() == 0) { - if (!readyTasks.add(new TaskContext(t, timeStep))) { + TaskContext tc = new TaskContext(t, timeStep); + if (!readyTasks.add(tc)) { + EventPrinter + .print("Time " + timeStep + ": Task " + tc + " could not be released!"); return false; } + EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!"); } } return true; diff --git a/src/main/java/mvd/jester/simulator/SchmidMottok.java b/src/main/java/mvd/jester/simulator/SchmidMottok.java index 5c435ad..f82f047 100644 --- a/src/main/java/mvd/jester/simulator/SchmidMottok.java +++ b/src/main/java/mvd/jester/simulator/SchmidMottok.java @@ -19,11 +19,13 @@ public class SchmidMottok extends AbstractSimulator { protected boolean releaseTasks(long timeStep) { for (Task t : systemSetup.getTasks()) { if (timeStep % t.getPeriod() == 0) { - TaskContext tc = new TaskContext(t, timeStep); + TaskContext tc = new TaskContext(t, systemSetup.getNumberOfProcessors(), timeStep); if (!readyTasks.add(tc)) { + EventPrinter + .print("Time " + timeStep + ": Task " + tc + " could not be released!"); return false; } - // System.out.println("Time " + timeStep + ": " + "Task " + tc + "activated!"); + EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!"); } } return true; diff --git a/src/main/java/mvd/jester/simulator/internals/JobContextInterface.java b/src/main/java/mvd/jester/simulator/internals/JobContextInterface.java index 9f67651..7a9c7a5 100644 --- a/src/main/java/mvd/jester/simulator/internals/JobContextInterface.java +++ b/src/main/java/mvd/jester/simulator/internals/JobContextInterface.java @@ -16,4 +16,6 @@ public interface JobContextInterface { public Optional getCurrentProcessor(); public TaskContextInterface getTaskContext(); + + public boolean prepareJob(long time); } diff --git a/src/main/java/mvd/jester/simulator/internals/ProcessorContext.java b/src/main/java/mvd/jester/simulator/internals/ProcessorContext.java index 2e017c2..733c512 100644 --- a/src/main/java/mvd/jester/simulator/internals/ProcessorContext.java +++ b/src/main/java/mvd/jester/simulator/internals/ProcessorContext.java @@ -1,6 +1,7 @@ package mvd.jester.simulator.internals; import java.util.Optional; +import mvd.jester.simulator.EventPrinter; /** * Processor @@ -41,17 +42,19 @@ public class ProcessorContext { Optional optionalJob = taskContext.getNextJob(); if (optionalJob.isPresent()) { + if (!optionalJob.get().prepareJob(t)) { + return false; + } if (currentJob.isPresent()) { currentJob.get().setCurrentProcessor(null); } currentJob = optionalJob; currentJob.get().setCurrentProcessor(this); - System.out.println( + EventPrinter.print( "Time " + t + ": " + this + " started job " + currentJob.get() + "!"); return true; - } else { - return false; } + } return false; diff --git a/src/main/java/mvd/jester/simulator/internals/maiabertogna/JobContext.java b/src/main/java/mvd/jester/simulator/internals/maiabertogna/JobContext.java index 3af705a..115a17e 100644 --- a/src/main/java/mvd/jester/simulator/internals/maiabertogna/JobContext.java +++ b/src/main/java/mvd/jester/simulator/internals/maiabertogna/JobContext.java @@ -1,6 +1,7 @@ package mvd.jester.simulator.internals.maiabertogna; import java.util.Optional; +import mvd.jester.simulator.EventPrinter; import mvd.jester.simulator.internals.JobContextInterface; import mvd.jester.simulator.internals.ProcessorContext; import mvd.jester.simulator.internals.TaskContextInterface; @@ -31,7 +32,7 @@ public class JobContext implements JobContextInterface { executionTime--; if (executionTime == 0) { - System.out.println("Time " + time + ": " + currentProcessor.get() + EventPrinter.print("Time " + time + ": " + currentProcessor.get() + " finished execution of job " + this + "!"); currentProcessor.get().setJob(null); currentProcessor = Optional.empty(); @@ -86,4 +87,9 @@ public class JobContext implements JobContextInterface { return "(jobWcet=" + wcet + ", of task=" + taskContext + ")"; } + @Override + public boolean prepareJob(long time) { + return true; + } + } diff --git a/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java b/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java index d1a7ead..b063aab 100644 --- a/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java +++ b/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Optional; import mvd.jester.model.Segment; import mvd.jester.model.Task; +import mvd.jester.simulator.EventPrinter; import mvd.jester.simulator.internals.JobContextInterface; import mvd.jester.simulator.internals.TaskContextInterface; @@ -52,7 +53,7 @@ public class TaskContext implements TaskContextInterface { currentSegment++; segmentCounter = 0; if (currentSegment >= segments.size()) { - System.out.println("Time " + time + ": Task " + this + "finished!"); + EventPrinter.print("Time " + time + ": Task " + this + "finished!"); return Optional.of(this); } } diff --git a/src/main/java/mvd/jester/simulator/internals/schmidmottok/JobContext.java b/src/main/java/mvd/jester/simulator/internals/schmidmottok/JobContext.java index 0f85486..410917a 100644 --- a/src/main/java/mvd/jester/simulator/internals/schmidmottok/JobContext.java +++ b/src/main/java/mvd/jester/simulator/internals/schmidmottok/JobContext.java @@ -1,6 +1,7 @@ package mvd.jester.simulator.internals.schmidmottok; import java.util.Optional; +import mvd.jester.simulator.EventPrinter; import mvd.jester.simulator.internals.JobContextInterface; import mvd.jester.simulator.internals.ProcessorContext; import mvd.jester.simulator.internals.TaskContextInterface; @@ -30,29 +31,36 @@ public class JobContext implements JobContextInterface { } public Optional updateExecution(long time) { - if (!currentTasklet.isPresent()) { + boolean jobIsIdle = true; + if (currentTasklet.isPresent()) { + jobIsIdle = currentTasklet.get().updateExecution(time); + } + + if (jobIsIdle) { currentTasklet = segmentContext.getNextTasklet(); + Optional tc = taskContext.acceptNotification(time); + if (currentTasklet.isPresent()) { - System.out.println("Time " + time + ": Job " + this + " started executing tasklet " + EventPrinter.print("Time " + time + ": Job " + this + " started executing tasklet " + currentTasklet.get() + " on Processor " + currentProcessor.get()); + currentTasklet.get().setCurrentJob(this); + } else { + if (currentProcessor.isPresent()) { + currentProcessor.get().setJob(null); + } + currentProcessor = Optional.empty(); + return tc; } } - if (currentTasklet.isPresent()) { - currentTasklet.get().setCurrentJob(this); - // Hier update execution time, dann checken if 0, und wenn 0 gleich nächste Tasklet - // auswählen. - return currentTasklet.get().updateExecution(time); - } else if (currentProcessor.isPresent()) { - currentProcessor.get().setJob(null); - currentProcessor = Optional.empty(); - } - return Optional.empty(); } public boolean checkExecutionTime() { - return executionTime > 0; + if (currentTasklet.isPresent()) { + return currentTasklet.get().checkExecutionTime(); + } + return false; } /** @@ -103,4 +111,21 @@ public class JobContext implements JobContextInterface { return "(of task=" + taskContext + ")"; } + @Override + public boolean prepareJob(long time) { + if (!currentTasklet.isPresent()) { + currentTasklet = segmentContext.getNextTasklet(); + if (currentTasklet.isPresent()) { + currentTasklet.get().setCurrentJob(this); + // EventPrinter.print("Time " + time + ": Job " + this + " started executing + // tasklet" + // + currentTasklet.get()); + return true; + } else { + return false; + } + } + return true; + } + } diff --git a/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java b/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java index fef06ab..d48ba65 100644 --- a/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java +++ b/src/main/java/mvd/jester/simulator/internals/schmidmottok/SegmentContext.java @@ -14,12 +14,15 @@ public class SegmentContext { private final Set jobs; private final Set tasklets; - public SegmentContext(TaskContext taskContext, Segment segment) { + public SegmentContext(TaskContext taskContext, Segment segment, long numberOfProcessors) { this.segment = segment; jobs = new HashSet<>(); tasklets = new HashSet<>(); - for (int j = 0; j < segment.getNumberOfJobs(); ++j) { + long numberOfJobs = segment.getNumberOfJobs() > numberOfProcessors ? numberOfProcessors + : segment.getNumberOfJobs(); + + for (int j = 0; j < numberOfJobs; ++j) { jobs.add(new JobContext(taskContext, this)); } @@ -36,14 +39,25 @@ public class SegmentContext { return segment; } + public long getNumberOfJobs() { + return jobs.size(); + } + Optional getNextJob() { boolean taskletAvailable = tasklets.stream() .anyMatch(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()); - if (taskletAvailable) { + boolean jobNotFinished = jobs.stream() + .anyMatch(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime()); + + if (jobNotFinished) { return jobs.stream() .filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime()) .findFirst(); + } else if (taskletAvailable) { + return jobs.stream() + .filter(j -> !j.getCurrentProcessor().isPresent() && !j.checkExecutionTime()) + .findFirst(); } else { return Optional.empty(); } diff --git a/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java b/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java index 2c2718c..f8fbda8 100644 --- a/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java +++ b/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Optional; import mvd.jester.model.Segment; import mvd.jester.model.Task; +import mvd.jester.simulator.EventPrinter; import mvd.jester.simulator.internals.JobContextInterface; import mvd.jester.simulator.internals.TaskContextInterface; @@ -19,7 +20,7 @@ public class TaskContext implements TaskContextInterface { private int segmentCounter; - public TaskContext(Task task, long timeStep) { + public TaskContext(Task task, long numberOfProcessors, long timeStep) { this.task = task; this.segments = new ArrayList<>(); this.currentSegment = 0; @@ -27,7 +28,7 @@ public class TaskContext implements TaskContextInterface { this.deadline = timeStep + task.getDeadline(); for (Segment s : task.getSegments()) { - segments.add(new SegmentContext(this, s)); + segments.add(new SegmentContext(this, s, numberOfProcessors)); } } @@ -52,7 +53,7 @@ public class TaskContext implements TaskContextInterface { currentSegment++; segmentCounter = 0; if (currentSegment >= segments.size()) { - System.out.println("Time " + time + ": Task " + this + "finished!"); + EventPrinter.print("Time " + time + ": Task " + this + "finished!"); return Optional.of(this); } } diff --git a/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskletContext.java b/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskletContext.java index 38f68ba..1c11e3f 100644 --- a/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskletContext.java +++ b/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskletContext.java @@ -1,7 +1,6 @@ package mvd.jester.simulator.internals.schmidmottok; import java.util.Optional; -import mvd.jester.simulator.internals.TaskContextInterface; /** * Tasklet @@ -33,15 +32,20 @@ public class TaskletContext { currentJob = Optional.ofNullable(jobContext); } - public Optional updateExecution(long time) { + /** + * @return true if tasklet finished, false otherwise + */ + public boolean updateExecution(long time) { executionTime--; if (executionTime == 0) { - currentJob.get().setCurrentTasklet(null); + if (currentJob.isPresent()) { + currentJob.get().setCurrentTasklet(null); + } currentJob = Optional.empty(); - return taskContext.acceptNotification(time); + return true; } - return Optional.empty(); + return false; } public boolean checkExecutionTime() {