From 4f83439408c5cfc694e4910fe4d40b1b99e5e290 Mon Sep 17 00:00:00 2001 From: Michael Schmid Date: Wed, 20 Nov 2019 15:11:24 +0100 Subject: [PATCH] added refactoring for Stats library --- src/main/java/mvd/jester/App.java | 16 +++++++++++----- src/main/java/mvd/jester/Pair.java | 36 ++++++++++++++++++++++++++++++++++++ src/main/java/mvd/jester/PairInterface.java | 11 +++++++++++ src/main/java/mvd/jester/ResultCollector.java | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/mvd/jester/TestEnvironment.java | 166 ++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------------------------------------------- src/main/java/mvd/jester/info/SchedulingInfo.java | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/mvd/jester/info/TerminationInfo.java | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/mvd/jester/model/SystemSetup.java | 11 ++++++++++- src/main/java/mvd/jester/simulator/AbstractSimulator.java | 28 ++++++++++++++++++---------- src/main/java/mvd/jester/simulator/SimulatorInterface.java | 3 ++- src/main/java/mvd/jester/simulator/internals/TaskContextInterface.java | 2 ++ src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java | 12 ++++++++++-- src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java | 13 +++++++++++-- src/main/java/mvd/jester/tests/AbstractTest.java | 9 ++++++--- src/main/java/mvd/jester/tests/MaiaBertogna.java | 19 ++++++++----------- src/main/java/mvd/jester/tests/SchmidMottok.java | 19 ++++++++----------- src/main/java/mvd/jester/tests/TestInterface.java | 3 ++- src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java | 1 - src/test/resources/Taskset1.txt | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/test/resources/Taskset2.txt | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/test/resources/Taskset3.txt | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 21 files changed, 777 insertions(+), 184 deletions(-) create mode 100644 src/main/java/mvd/jester/Pair.java create mode 100644 src/main/java/mvd/jester/PairInterface.java create mode 100644 src/main/java/mvd/jester/ResultCollector.java create mode 100644 src/main/java/mvd/jester/info/SchedulingInfo.java create mode 100644 src/main/java/mvd/jester/info/TerminationInfo.java create mode 100644 src/test/resources/Taskset1.txt create mode 100644 src/test/resources/Taskset2.txt create mode 100644 src/test/resources/Taskset3.txt diff --git a/src/main/java/mvd/jester/App.java b/src/main/java/mvd/jester/App.java index 5524c6e..e648983 100644 --- a/src/main/java/mvd/jester/App.java +++ b/src/main/java/mvd/jester/App.java @@ -12,17 +12,23 @@ import mvd.jester.priority.RateMonotonic; public class App { public static void main(String[] args) { SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); - TestEnvironment te = new TestEnvironment(builder, 40000); + TestEnvironment te = new TestEnvironment(builder, 30000); te.registerSchedulingAlgorithm(new RateMonotonic()); te.registerSchedulingAlgorithm(new EarliestDeadlineFirst()); - te.registerTestPair(mvd.jester.tests.MaiaBertogna.class, - mvd.jester.simulator.MaiaBertogna.class); + // te.registerTest(mvd.jester.tests.SchmidMottok.class); + // te.registerTest(mvd.jester.tests.MaiaBertogna.class); + + te.registerSimulator(mvd.jester.simulator.MaiaBertogna.class); + te.registerSimulator(mvd.jester.simulator.SchmidMottok.class); - te.registerTestPair(mvd.jester.tests.SchmidMottok.class, - mvd.jester.simulator.SchmidMottok.class); te.runTests(); + + // SystemSetup ss = builder.build(); + // builder.addTask(ss); + // builder.addTask(ss); + // ss.writeToFile("Test3.txt"); } } diff --git a/src/main/java/mvd/jester/Pair.java b/src/main/java/mvd/jester/Pair.java new file mode 100644 index 0000000..828340a --- /dev/null +++ b/src/main/java/mvd/jester/Pair.java @@ -0,0 +1,36 @@ +package mvd.jester; + +import mvd.jester.priority.PriorityManager; + +/** + * PriorityPair + */ +public class Pair { + private final PriorityManager priorityManager; + private final T abstractValue; + + + public Pair(PriorityManager priorityManager, T abstractValue) { + this.abstractValue = abstractValue; + this.priorityManager = priorityManager; + } + + /** + * @return the priorityManager + */ + public PriorityManager getPriorityManager() { + return priorityManager; + } + + /** + * @return the abstractValue + */ + public T getAbstractValue() { + return abstractValue; + } + + public String getName() { + return abstractValue.getName() + "_" + priorityManager.getName(); + } + +} diff --git a/src/main/java/mvd/jester/PairInterface.java b/src/main/java/mvd/jester/PairInterface.java new file mode 100644 index 0000000..393b0cf --- /dev/null +++ b/src/main/java/mvd/jester/PairInterface.java @@ -0,0 +1,11 @@ +package mvd.jester; + +/** + * PairInterface + */ +public interface PairInterface { + public String getName(); + + +} + diff --git a/src/main/java/mvd/jester/ResultCollector.java b/src/main/java/mvd/jester/ResultCollector.java new file mode 100644 index 0000000..00d27db --- /dev/null +++ b/src/main/java/mvd/jester/ResultCollector.java @@ -0,0 +1,160 @@ +package mvd.jester; + +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import com.google.common.collect.Table; +import com.google.common.math.Stats; +import mvd.jester.info.SchedulingInfo; +import mvd.jester.info.TerminationInfo; +import mvd.jester.simulator.AbstractSimulator; +import mvd.jester.tests.AbstractTest; +import mvd.jester.utils.Logger; + +/** + * ResultCollector + */ +public class ResultCollector { + + private final Table, Set> testResults; + private final Table, Set> simulatorResults; + private final Map totalNumberOfTasksets; + private final long numberOfProcessors; + + public ResultCollector(Table, Set> testResults, + Table, Set> simulatorResults, + Map totalNumberOfTasksets, long numberOfProcessors) { + this.testResults = testResults; + this.simulatorResults = simulatorResults; + this.totalNumberOfTasksets = totalNumberOfTasksets; + this.numberOfProcessors = numberOfProcessors; + } + + public void logAll() { + if (!testResults.isEmpty()) { + logResults(testResults, "test"); + logMeanTardiness(simulatorResults, "test"); + logFailedTardiness(testResults, "test"); + } + if (!simulatorResults.isEmpty()) { + logResults(simulatorResults, "sim"); + logMeanTardiness(simulatorResults, "sim"); + logFailedTardiness(simulatorResults, "sim"); + } + } + + public void logResults( + Table, Set> results, String type) { + LocalTime date = LocalTime.now(); + Logger log = new Logger("./results/results_" + type + "_" + numberOfProcessors + "_" + + date.getHour() + ":" + date.getMinute() + ".txt"); + String firstLine = new String("Utilization\tTotal"); + + if (!results.isEmpty()) { + for (Pair pair : results.columnKeySet()) { + firstLine = firstLine + "\t" + pair.getName(); + } + + log.log(firstLine); + + for (Long util : totalNumberOfTasksets.keySet()) { + String line = + String.valueOf((double) util / 10) + "\t" + totalNumberOfTasksets.get(util); + for (Pair pair : results.columnKeySet()) { + long feasibleTasksets = results.get(util, pair).stream() + .filter(s -> s.checkTasksetFeasible()).count(); + line += "\t" + feasibleTasksets; + } + log.log(line); + } + } + + log.finalize(); + } + + + public void logFailedTardiness( + Table, Set> results, String type) { + LocalTime date = LocalTime.now(); + Logger log = new Logger("./results/failed_tardiness_" + type + "_" + numberOfProcessors + + "_" + date.getHour() + ":" + date.getMinute() + ".txt"); + String firstLine = new String("Utilization\tTotal"); + + if (!results.isEmpty()) { + for (Pair pair : results.columnKeySet()) { + firstLine = firstLine + "\t" + pair.getName(); + } + + log.log(firstLine); + + for (Long kv : totalNumberOfTasksets.keySet()) { + String line = + String.valueOf((double) kv / 10) + "\t" + totalNumberOfTasksets.get(kv); + for (Pair pair : results.columnKeySet()) { + Set simulationInfos = results.get(kv, pair); + List values = new ArrayList<>(); + + for (SchedulingInfo s : simulationInfos) { + Optional failedTerminationInfo = + s.getFailedTerminationInfo(); + if (failedTerminationInfo.isPresent()) { + values.add(failedTerminationInfo.get().getLateness()); + } + } + double meanTardiness = 0; + if (!values.isEmpty()) { + meanTardiness = Stats.meanOf(values.iterator()); + } + line += "\t" + meanTardiness; + } + log.log(line); + } + } + + log.finalize(); + } + + public void logMeanTardiness( + Table, Set> results, String type) { + LocalTime date = LocalTime.now(); + Logger log = new Logger("./results/mean_tardiness_" + type + "_" + numberOfProcessors + "_" + + date.getHour() + ":" + date.getMinute() + ".txt"); + String firstLine = new String("Utilization\tTotal"); + + if (!results.isEmpty()) { + for (Pair pair : results.columnKeySet()) { + firstLine = firstLine + "\t" + pair.getName(); + } + + log.log(firstLine); + + for (Long kv : totalNumberOfTasksets.keySet()) { + String line = + String.valueOf((double) kv / 10) + "\t" + totalNumberOfTasksets.get(kv); + for (Pair pair : results.columnKeySet()) { + Set simulationInfos = results.get(kv, pair); + List values = new ArrayList<>(); + + for (SchedulingInfo s : simulationInfos) { + for (TerminationInfo t : s.getTerminationInfos()) { + values.add(t.getLateness()); + } + } + + double meanTardiness = 0; + if (!values.isEmpty()) { + meanTardiness = Stats.meanOf(values.iterator()); + } + line += "\t" + meanTardiness; + } + log.log(line); + } + } + + log.finalize(); + } + +} diff --git a/src/main/java/mvd/jester/TestEnvironment.java b/src/main/java/mvd/jester/TestEnvironment.java index 7315db5..09c8464 100644 --- a/src/main/java/mvd/jester/TestEnvironment.java +++ b/src/main/java/mvd/jester/TestEnvironment.java @@ -1,18 +1,17 @@ package mvd.jester; import java.lang.reflect.Constructor; -import java.time.LocalTime; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; +import mvd.jester.info.SchedulingInfo; import mvd.jester.model.SystemSetup; import mvd.jester.priority.PriorityManager; import mvd.jester.simulator.AbstractSimulator; import mvd.jester.tests.AbstractTest; -import mvd.jester.utils.Logger; /** * TestEnvironment @@ -79,18 +78,20 @@ public class TestEnvironment { } public void runTests() { - Set abstractTestInstances = new HashSet<>(); - Set abstractSimulatorInstances = new HashSet<>(); + Set> abstractTestInstances = new HashSet<>(); + Set> abstractSimulatorInstances = new HashSet<>(); - Map totalNumberOfTasks = new HashMap<>(); + Map totalNumberOfTasksets = new HashMap<>(); - Table testResults = HashBasedTable.create(); - Table simulatorResults = HashBasedTable.create(); + Table, Set> testResults = HashBasedTable.create(); + Table, Set> simulatorResults = + HashBasedTable.create(); for (PriorityManager pm : schedulingAlgorithms) { for (Constructor c : abstractTests) { try { - abstractTestInstances.add(new TestPair(pm, c.newInstance(this.systemSetup))); + abstractTestInstances + .add(new Pair(pm, c.newInstance(this.systemSetup))); } catch (Exception e) { System.out.println("Could not instantiate object of AbstractTest!"); } @@ -99,7 +100,7 @@ public class TestEnvironment { for (Constructor c : abstractSimulators) { try { abstractSimulatorInstances - .add(new SimulatorPair(pm, c.newInstance(this.systemSetup))); + .add(new Pair(pm, c.newInstance(this.systemSetup))); } catch (Exception e) { System.out.println("Could not instantiate object of AbstractSimulator!"); } @@ -123,33 +124,35 @@ public class TestEnvironment { long roundedUtilization = (long) (utilization * 10); - totalNumberOfTasks.compute(roundedUtilization, (k, v) -> v == null ? 1 : v + 1); + totalNumberOfTasksets.compute(roundedUtilization, (k, v) -> v == null ? 1 : v + 1); - for (TestPair testInstance : abstractTestInstances) { + for (Pair testInstance : abstractTestInstances) { PriorityManager priorityManager = testInstance.getPriorityManager(); - AbstractTest abstractTest = testInstance.getAbstractTest(); + AbstractTest abstractTest = testInstance.getAbstractValue(); if (!testResults.contains(roundedUtilization, testInstance)) { - testResults.put(roundedUtilization, testInstance, (long) 0); + testResults.put(roundedUtilization, testInstance, new HashSet<>()); } - if (priorityManager.hasTest(abstractTest) - && abstractTest.runSchedulabilityCheck(priorityManager)) { - Long val = testResults.get(roundedUtilization, testInstance); - testResults.put(roundedUtilization, testInstance, val + 1); + if (priorityManager.hasTest(abstractTest)) { + SchedulingInfo schedulingInfo = + abstractTest.runSchedulabilityCheck(priorityManager); + testResults.get(roundedUtilization, testInstance).add(schedulingInfo); } } - for (SimulatorPair simulatorInstance : abstractSimulatorInstances) { + for (Pair simulatorInstance : abstractSimulatorInstances) { PriorityManager priorityManager = simulatorInstance.getPriorityManager(); - AbstractSimulator abstractSimulator = simulatorInstance.getAbstractSimulator(); + AbstractSimulator abstractSimulator = simulatorInstance.getAbstractValue(); if (!simulatorResults.contains(roundedUtilization, simulatorInstance)) { - simulatorResults.put(roundedUtilization, simulatorInstance, (long) 0); + simulatorResults.put(roundedUtilization, simulatorInstance, + new HashSet<>()); } - if (priorityManager.hasSimulator(abstractSimulator) - && abstractSimulator.runSimulation(priorityManager)) { - Long val = simulatorResults.get(roundedUtilization, simulatorInstance); - simulatorResults.put(roundedUtilization, simulatorInstance, val + 1); + if (priorityManager.hasSimulator(abstractSimulator)) { + SchedulingInfo schedulingInfo = + abstractSimulator.runSimulation(priorityManager); + simulatorResults.get(roundedUtilization, simulatorInstance) + .add(schedulingInfo); } } @@ -159,121 +162,12 @@ public class TestEnvironment { } } - logTestResults(testResults, totalNumberOfTasks); - logSimulationResults(simulatorResults, totalNumberOfTasks); - } - - private void logTestResults(Table results, - Map totalNumberOfTasks) { - LocalTime date = LocalTime.now(); - Logger log = new Logger("./results/results_" + systemSetup.getNumberOfProcessors() + "_" - + date.getHour() + ":" + date.getMinute() + ".txt"); - String firstLine = new String("Utilization"); - - if (!results.isEmpty()) { - for (TestPair testPair : results.columnKeySet()) { - firstLine = firstLine + "\t" + testPair.getName(); - } - - log.log(firstLine); + ResultCollector resultCollector = new ResultCollector(testResults, simulatorResults, + totalNumberOfTasksets, systemSetup.getNumberOfProcessors()); - for (Long util : totalNumberOfTasks.keySet()) { - String line = - String.valueOf((double) util / 10) + "\t" + totalNumberOfTasks.get(util); - for (TestPair simulatorPair : results.columnKeySet()) { - line += "\t" + results.get(util, simulatorPair); - } - log.log(line); - } - } - - log.finalize(); + resultCollector.logAll(); } - private void logSimulationResults(Table results, - Map totalNumberOfTasks) { - LocalTime date = LocalTime.now(); - Logger log = new Logger("./results/results_sim_" + systemSetup.getNumberOfProcessors() + "_" - + date.getHour() + ":" + date.getMinute() + ".txt"); - String firstLine = new String("Utilization\tTotal"); - - if (!results.isEmpty()) { - for (SimulatorPair simulatorPair : results.columnKeySet()) { - firstLine = firstLine + "\t" + simulatorPair.getName(); - } - - log.log(firstLine); - - for (Long kv : totalNumberOfTasks.keySet()) { - String line = String.valueOf((double) kv / 10) + "\t" + totalNumberOfTasks.get(kv); - for (SimulatorPair simulatorPair : results.columnKeySet()) { - line += "\t" + results.get(kv, simulatorPair); - } - log.log(line); - } - } - - log.finalize(); - } - - - private class SimulatorPair { - private final PriorityManager priorityManager; - private final AbstractSimulator abstractSimulator; - - - public SimulatorPair(PriorityManager priorityManager, AbstractSimulator abstractSimulator) { - this.abstractSimulator = abstractSimulator; - this.priorityManager = priorityManager; - } - - /** - * @return the priorityManager - */ - public PriorityManager getPriorityManager() { - return priorityManager; - } - - /** - * @return the abstractSimulator - */ - public AbstractSimulator getAbstractSimulator() { - return abstractSimulator; - } - - public String getName() { - return abstractSimulator.getName() + "_" + priorityManager.getName(); - } - } - - private class TestPair { - private final PriorityManager priorityManager; - private final AbstractTest abstractTest; - - - public TestPair(PriorityManager priorityManager, AbstractTest abstractTest) { - this.abstractTest = abstractTest; - this.priorityManager = priorityManager; - } - - /** - * @return the priorityManager - */ - public PriorityManager getPriorityManager() { - return priorityManager; - } - - /** - * @return the abstractTest - */ - public AbstractTest getAbstractTest() { - return abstractTest; - } - - public String getName() { - return abstractTest.getName() + "_" + priorityManager.getName(); - } - } } diff --git a/src/main/java/mvd/jester/info/SchedulingInfo.java b/src/main/java/mvd/jester/info/SchedulingInfo.java new file mode 100644 index 0000000..99e3d3e --- /dev/null +++ b/src/main/java/mvd/jester/info/SchedulingInfo.java @@ -0,0 +1,50 @@ +package mvd.jester.info; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +/** + * DeadlineMissInfo + */ +public class SchedulingInfo { + + private final Set terminationInfos; + private Optional failedTerminationInfo; + + public SchedulingInfo() { + this.terminationInfos = new HashSet<>(); + this.failedTerminationInfo = Optional.empty(); + } + + public SchedulingInfo(Set terminationInfos) { + this.terminationInfos = terminationInfos; + } + + public boolean checkTasksetFeasible() { + // return terminationInfos.isEmpty(); + return !terminationInfos.stream().anyMatch(t -> t.getLateness() > 0); + } + + public void addTerminationInfo(TerminationInfo terminationInfo) { + terminationInfos.add(terminationInfo); + } + + /** + * @return the terminationInfos + */ + public Set getTerminationInfos() { + return terminationInfos; + } + + /** + * @return the failedTerminationInfo + */ + public Optional getFailedTerminationInfo() { + return failedTerminationInfo; + } + + public void setFailedTemrinationInfo(TerminationInfo failedTerminationInfo) { + this.failedTerminationInfo = Optional.of(failedTerminationInfo); + } +} diff --git a/src/main/java/mvd/jester/info/TerminationInfo.java b/src/main/java/mvd/jester/info/TerminationInfo.java new file mode 100644 index 0000000..b75a906 --- /dev/null +++ b/src/main/java/mvd/jester/info/TerminationInfo.java @@ -0,0 +1,48 @@ +package mvd.jester.info; + +/** + * TerminationInfo + */ +public class TerminationInfo { + + private final long releaseTime; + private final long deadline; + private final long responseTime; + private final long lateness; + + public TerminationInfo(long releaseTime, long deadline, long responseTime) { + this.releaseTime = releaseTime; + this.deadline = deadline; + this.responseTime = responseTime; + this.lateness = responseTime - deadline; + } + + + /** + * @return the deadline + */ + public long getDeadline() { + return deadline; + } + + /** + * @return the lateness + */ + public long getLateness() { + return lateness; + } + + /** + * @return the releaseTime + */ + public long getReleaseTime() { + return releaseTime; + } + + /** + * @return the responseTime + */ + public long getResponseTime() { + return responseTime; + } +} diff --git a/src/main/java/mvd/jester/model/SystemSetup.java b/src/main/java/mvd/jester/model/SystemSetup.java index 9ab198c..c227375 100644 --- a/src/main/java/mvd/jester/model/SystemSetup.java +++ b/src/main/java/mvd/jester/model/SystemSetup.java @@ -1,6 +1,7 @@ package mvd.jester.model; import java.io.IOException; +import java.io.PrintWriter; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; @@ -56,7 +57,15 @@ public class SystemSetup { return gson.toJson(tasks); } - public static SystemSetup fromFile(String path) { + public void writeToFile(String path) { + try (PrintWriter pw = new PrintWriter(path)) { + pw.write(toString()); + } catch (Exception e) { + System.err.println("Something went wrong when writing to file!"); + } + } + + public static SystemSetup readFromFile(String path) { String jsonString; try { byte[] encoded = Files.readAllBytes(Paths.get(path)); diff --git a/src/main/java/mvd/jester/simulator/AbstractSimulator.java b/src/main/java/mvd/jester/simulator/AbstractSimulator.java index 76847ff..6a7e9d7 100644 --- a/src/main/java/mvd/jester/simulator/AbstractSimulator.java +++ b/src/main/java/mvd/jester/simulator/AbstractSimulator.java @@ -5,28 +5,31 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import com.google.common.collect.TreeMultiset; import mvd.jester.model.SystemSetup; import mvd.jester.model.Task; import mvd.jester.priority.PriorityManager; import mvd.jester.priority.RateMonotonic; +import mvd.jester.PairInterface; +import mvd.jester.info.SchedulingInfo; +import mvd.jester.info.TerminationInfo; import mvd.jester.simulator.internals.ProcessorContext; -import mvd.jester.simulator.internals.SortedTaskContextSet; import mvd.jester.simulator.internals.TaskContextInterface; /** * AbstractSimulator */ -public abstract class AbstractSimulator implements SimulatorInterface { +public abstract class AbstractSimulator implements SimulatorInterface, PairInterface { protected final SystemSetup systemSetup; protected final Set processors; - protected Set readyTasks; + protected TreeMultiset readyTasks; protected long hyperPeriod; AbstractSimulator(SystemSetup systemSetup) { this.systemSetup = systemSetup; - this.readyTasks = new SortedTaskContextSet(new RateMonotonic()); + this.readyTasks = TreeMultiset.create((t1, t2) -> new RateMonotonic().compare(t1, t2)); processors = new HashSet<>(); for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) { processors.add(new ProcessorContext(i)); @@ -39,11 +42,12 @@ public abstract class AbstractSimulator implements SimulatorInterface { protected abstract boolean releaseTasks(long timeStep); @Override - public boolean runSimulation(PriorityManager priorityManager) { + public SchedulingInfo runSimulation(PriorityManager priorityManager) { + SchedulingInfo schedulingInfo = new SchedulingInfo(); init(priorityManager); for (int t = 0; t < hyperPeriod; ++t) { if (!releaseTasks(t)) { - return false; + throw new RuntimeException("Could not release a task. This should not happen!"); } Set sortedProcessors = sortProcessors(processors); @@ -61,20 +65,25 @@ public abstract class AbstractSimulator implements SimulatorInterface { Optional optionalTc = p.updateExecution(t); if (optionalTc.isPresent()) { TaskContextInterface tc = optionalTc.get(); + TerminationInfo terminationInfo = + new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t); + schedulingInfo.addTerminationInfo(terminationInfo); if (t >= tc.getDeadline()) { EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!"); - return false; + schedulingInfo.setFailedTemrinationInfo(terminationInfo); + return schedulingInfo; } + readyTasks.remove(optionalTc.get()); } } } - return true; + return schedulingInfo; } private void init(PriorityManager priorityManager) { - this.readyTasks = new SortedTaskContextSet(priorityManager); + this.readyTasks = TreeMultiset.create((t1, t2) -> priorityManager.compare(t1, t2)); for (ProcessorContext p : processors) { p.setJob(null); } @@ -115,5 +124,4 @@ public abstract class AbstractSimulator implements SimulatorInterface { } } - } diff --git a/src/main/java/mvd/jester/simulator/SimulatorInterface.java b/src/main/java/mvd/jester/simulator/SimulatorInterface.java index a4eae6e..f95461a 100644 --- a/src/main/java/mvd/jester/simulator/SimulatorInterface.java +++ b/src/main/java/mvd/jester/simulator/SimulatorInterface.java @@ -1,5 +1,6 @@ package mvd.jester.simulator; +import mvd.jester.info.SchedulingInfo; import mvd.jester.priority.PriorityManager; /** @@ -7,7 +8,7 @@ import mvd.jester.priority.PriorityManager; */ public interface SimulatorInterface { - public boolean runSimulation(PriorityManager priorityManager); + public SchedulingInfo runSimulation(PriorityManager priorityManager); public String getName(); diff --git a/src/main/java/mvd/jester/simulator/internals/TaskContextInterface.java b/src/main/java/mvd/jester/simulator/internals/TaskContextInterface.java index 8cb8d78..e925d0c 100644 --- a/src/main/java/mvd/jester/simulator/internals/TaskContextInterface.java +++ b/src/main/java/mvd/jester/simulator/internals/TaskContextInterface.java @@ -15,4 +15,6 @@ public interface TaskContextInterface { public Optional getNextJob(); public long getDeadline(); + + public long getReleaseTime(); } 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 81b5766..adfab81 100644 --- a/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java +++ b/src/main/java/mvd/jester/simulator/internals/maiabertogna/TaskContext.java @@ -16,16 +16,18 @@ public class TaskContext implements TaskContextInterface { private final Task task; private final ArrayList segments; private final long deadline; + private final long releaseTime; private int currentSegment; private int segmentCounter; - public TaskContext(Task task, long timeStep) { + public TaskContext(Task task, long releaseTime) { this.task = task; this.segments = new ArrayList<>(); this.currentSegment = 0; this.segmentCounter = 0; - this.deadline = timeStep + task.getDeadline(); + this.releaseTime = releaseTime; + this.deadline = releaseTime + task.getDeadline(); for (Segment s : task.getSegments()) { segments.add(new SegmentContext(this, s)); @@ -42,10 +44,16 @@ public class TaskContext implements TaskContextInterface { /** * @return the deadline */ + @Override public long getDeadline() { return deadline; } + @Override + public long getReleaseTime() { + return releaseTime; + } + public Optional acceptNotification(long time) { segmentCounter++; 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 035aeb0..587c0cb 100644 --- a/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java +++ b/src/main/java/mvd/jester/simulator/internals/schmidmottok/TaskContext.java @@ -15,17 +15,19 @@ public class TaskContext implements TaskContextInterface { private final Task task; private final ArrayList segments; + private final long releaseTime; private final long deadline; private int currentSegment; private int segmentCounter; - public TaskContext(Task task, long numberOfProcessors, long timeStep) { + public TaskContext(Task task, long numberOfProcessors, long releaseTime) { this.task = task; this.segments = new ArrayList<>(); this.currentSegment = 0; this.segmentCounter = 0; - this.deadline = timeStep + task.getDeadline(); + this.deadline = releaseTime + task.getDeadline(); + this.releaseTime = releaseTime; for (Segment s : task.getSegments()) { segments.add(new SegmentContext(this, s, numberOfProcessors)); @@ -42,10 +44,16 @@ public class TaskContext implements TaskContextInterface { /** * @return the deadline */ + @Override public long getDeadline() { return deadline; } + @Override + public long getReleaseTime() { + return releaseTime; + } + public Optional acceptNotification(long time) { segmentCounter++; @@ -76,4 +84,5 @@ public class TaskContext implements TaskContextInterface { return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments=" + segments.size() + ")"; } + } diff --git a/src/main/java/mvd/jester/tests/AbstractTest.java b/src/main/java/mvd/jester/tests/AbstractTest.java index 49ba9b2..32335a2 100644 --- a/src/main/java/mvd/jester/tests/AbstractTest.java +++ b/src/main/java/mvd/jester/tests/AbstractTest.java @@ -3,21 +3,24 @@ package mvd.jester.tests; import java.util.HashMap; import java.util.Map; import java.util.Set; +import mvd.jester.PairInterface; +import mvd.jester.info.TerminationInfo; import mvd.jester.model.SystemSetup; import mvd.jester.model.Task; /** * AbstractTest */ -public abstract class AbstractTest implements TestInterface { +public abstract class AbstractTest implements TestInterface, PairInterface { - protected final Map responseTimes; + protected final Map responseTimes; protected final SystemSetup systemSetup; protected Set tasks; public AbstractTest(SystemSetup systemSetup) { this.systemSetup = systemSetup; - this.responseTimes = new HashMap(); + this.responseTimes = new HashMap<>(); this.tasks = systemSetup.getTasks(); } + } diff --git a/src/main/java/mvd/jester/tests/MaiaBertogna.java b/src/main/java/mvd/jester/tests/MaiaBertogna.java index 4a6eaa2..353a929 100644 --- a/src/main/java/mvd/jester/tests/MaiaBertogna.java +++ b/src/main/java/mvd/jester/tests/MaiaBertogna.java @@ -1,8 +1,10 @@ package mvd.jester.tests; import java.math.RoundingMode; -import java.util.Map.Entry; +import java.util.HashSet; import com.google.common.math.LongMath; +import mvd.jester.info.SchedulingInfo; +import mvd.jester.info.TerminationInfo; import mvd.jester.model.Segment; import mvd.jester.model.SortedTaskSet; import mvd.jester.model.Task; @@ -19,21 +21,16 @@ public class MaiaBertogna extends AbstractTest { } @Override - public boolean runSchedulabilityCheck(PriorityManager priorityManager) { + public SchedulingInfo runSchedulabilityCheck(PriorityManager priorityManager) { tasks = new SortedTaskSet(priorityManager); tasks.addAll(systemSetup.getTasks()); responseTimes.clear(); for (Task t : tasks) { - responseTimes.put(t, calculateResponseTime(t)); + long responseTime = calculateResponseTime(t); + responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); } - for (Entry keyValuePair : responseTimes.entrySet()) { - if (keyValuePair.getKey().getDeadline() < keyValuePair.getValue().longValue()) { - return false; - } - } - - return true; + return new SchedulingInfo(new HashSet<>(responseTimes.values())); } @Override @@ -92,7 +89,7 @@ public class MaiaBertogna extends AbstractTest { private long getTaskInterference(Task task, long interval, long parallelism) { if (responseTimes.containsKey(task)) { - long responseTime = responseTimes.get(task); + long responseTime = responseTimes.get(task).getResponseTime(); long minWcet = getMinimumWcet(task); long period = task.getPeriod(); long numberOfJobs = diff --git a/src/main/java/mvd/jester/tests/SchmidMottok.java b/src/main/java/mvd/jester/tests/SchmidMottok.java index 16d278f..a43f38a 100644 --- a/src/main/java/mvd/jester/tests/SchmidMottok.java +++ b/src/main/java/mvd/jester/tests/SchmidMottok.java @@ -1,8 +1,10 @@ package mvd.jester.tests; import java.math.RoundingMode; -import java.util.Map.Entry; +import java.util.HashSet; import com.google.common.math.LongMath; +import mvd.jester.info.SchedulingInfo; +import mvd.jester.info.TerminationInfo; import mvd.jester.model.Segment; import mvd.jester.model.SortedTaskSet; import mvd.jester.model.Task; @@ -19,21 +21,16 @@ public class SchmidMottok extends AbstractTest { } @Override - public boolean runSchedulabilityCheck(PriorityManager priorityManager) { + public SchedulingInfo runSchedulabilityCheck(PriorityManager priorityManager) { tasks = new SortedTaskSet(priorityManager); tasks.addAll(systemSetup.getTasks()); responseTimes.clear(); for (Task t : tasks) { - responseTimes.put(t, calculateResponseTime(t)); + long responseTime = calculateResponseTime(t); + responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); } - for (Entry taskResponsePair : responseTimes.entrySet()) { - if (taskResponsePair.getKey().getDeadline() < taskResponsePair.getValue().longValue()) { - return false; - } - } - - return true; + return new SchedulingInfo(new HashSet<>(responseTimes.values())); } @Override @@ -93,7 +90,7 @@ public class SchmidMottok extends AbstractTest { private double getTaskInterference(Task task, long interval, long parallelism) { if (responseTimes.containsKey(task)) { - long responseTime = responseTimes.get(task); + long responseTime = responseTimes.get(task).getResponseTime(); long minWcet = getMinimumWcet(task); long period = task.getPeriod(); long numberOfProcessors = systemSetup.getNumberOfProcessors(); diff --git a/src/main/java/mvd/jester/tests/TestInterface.java b/src/main/java/mvd/jester/tests/TestInterface.java index b4d9a4e..b8a104d 100644 --- a/src/main/java/mvd/jester/tests/TestInterface.java +++ b/src/main/java/mvd/jester/tests/TestInterface.java @@ -1,5 +1,6 @@ package mvd.jester.tests; +import mvd.jester.info.SchedulingInfo; import mvd.jester.priority.PriorityManager; /** @@ -7,7 +8,7 @@ import mvd.jester.priority.PriorityManager; */ public interface TestInterface { - public boolean runSchedulabilityCheck(PriorityManager priorityManager); + public SchedulingInfo runSchedulabilityCheck(PriorityManager priorityManager); public String getName(); diff --git a/src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java b/src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java index d6a105c..1f3aa7c 100644 --- a/src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java +++ b/src/test/java/mvd/jester/simulator/schmidmottok/TestJobContext.java @@ -5,7 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.AdditionalMatchers.not; -import static org.mockito.AdditionalMatchers.gt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/src/test/resources/Taskset1.txt b/src/test/resources/Taskset1.txt new file mode 100644 index 0000000..e58f8a8 --- /dev/null +++ b/src/test/resources/Taskset1.txt @@ -0,0 +1,136 @@ +[ + { + "deadline": 487, + "period": 487, + "segments": [ + { + "jobWcet": 24, + "numberOfJobs": 1, + "taskletWcet": 24, + "numberOfTasklets": 1 + }, + { + "jobWcet": 27, + "numberOfJobs": 10, + "taskletWcet": 10, + "numberOfTasklets": 27 + }, + { + "jobWcet": 40, + "numberOfJobs": 1, + "taskletWcet": 40, + "numberOfTasklets": 1 + }, + { + "jobWcet": 17, + "numberOfJobs": 10, + "taskletWcet": 10, + "numberOfTasklets": 17 + }, + { + "jobWcet": 96, + "numberOfJobs": 1, + "taskletWcet": 96, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 600, + "maximumParallelism": 10 + }, + { + "deadline": 781, + "period": 781, + "segments": [ + { + "jobWcet": 59, + "numberOfJobs": 1, + "taskletWcet": 59, + "numberOfTasklets": 1 + }, + { + "jobWcet": 74, + "numberOfJobs": 6, + "taskletWcet": 6, + "numberOfTasklets": 74 + }, + { + "jobWcet": 82, + "numberOfJobs": 1, + "taskletWcet": 82, + "numberOfTasklets": 1 + }, + { + "jobWcet": 30, + "numberOfJobs": 6, + "taskletWcet": 6, + "numberOfTasklets": 30 + }, + { + "jobWcet": 18, + "numberOfJobs": 1, + "taskletWcet": 18, + "numberOfTasklets": 1 + }, + { + "jobWcet": 79, + "numberOfJobs": 6, + "taskletWcet": 6, + "numberOfTasklets": 79 + } + ], + "maximumWcet": 1257, + "maximumParallelism": 6 + }, + { + "deadline": 494, + "period": 494, + "segments": [ + { + "jobWcet": 413, + "numberOfJobs": 1, + "taskletWcet": 413, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 413, + "maximumParallelism": 1 + }, + { + "deadline": 496, + "period": 496, + "segments": [ + { + "jobWcet": 84, + "numberOfJobs": 1, + "taskletWcet": 84, + "numberOfTasklets": 1 + }, + { + "jobWcet": 52, + "numberOfJobs": 5, + "taskletWcet": 5, + "numberOfTasklets": 52 + }, + { + "jobWcet": 78, + "numberOfJobs": 1, + "taskletWcet": 78, + "numberOfTasklets": 1 + }, + { + "jobWcet": 53, + "numberOfJobs": 5, + "taskletWcet": 5, + "numberOfTasklets": 53 + }, + { + "jobWcet": 57, + "numberOfJobs": 1, + "taskletWcet": 57, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 744, + "maximumParallelism": 5 + } +] \ No newline at end of file diff --git a/src/test/resources/Taskset2.txt b/src/test/resources/Taskset2.txt new file mode 100644 index 0000000..9d2f90e --- /dev/null +++ b/src/test/resources/Taskset2.txt @@ -0,0 +1,132 @@ +[ + { + "deadline": 677, + "period": 677, + "segments": [ + { + "jobWcet": 214, + "numberOfJobs": 1, + "taskletWcet": 214, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 214, + "maximumParallelism": 1 + }, + { + "deadline": 694, + "period": 694, + "segments": [ + { + "jobWcet": 12, + "numberOfJobs": 1, + "taskletWcet": 12, + "numberOfTasklets": 1 + }, + { + "jobWcet": 217, + "numberOfJobs": 2, + "taskletWcet": 2, + "numberOfTasklets": 217 + }, + { + "jobWcet": 228, + "numberOfJobs": 1, + "taskletWcet": 228, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 674, + "maximumParallelism": 2 + }, + { + "deadline": 807, + "period": 807, + "segments": [ + { + "jobWcet": 11, + "numberOfJobs": 1, + "taskletWcet": 11, + "numberOfTasklets": 1 + }, + { + "jobWcet": 115, + "numberOfJobs": 9, + "taskletWcet": 9, + "numberOfTasklets": 115 + }, + { + "jobWcet": 6, + "numberOfJobs": 1, + "taskletWcet": 6, + "numberOfTasklets": 1 + }, + { + "jobWcet": 119, + "numberOfJobs": 9, + "taskletWcet": 9, + "numberOfTasklets": 119 + }, + { + "jobWcet": 38, + "numberOfJobs": 1, + "taskletWcet": 38, + "numberOfTasklets": 1 + }, + { + "jobWcet": 38, + "numberOfJobs": 9, + "taskletWcet": 9, + "numberOfTasklets": 38 + } + ], + "maximumWcet": 2503, + "maximumParallelism": 9 + }, + { + "deadline": 871, + "period": 871, + "segments": [ + { + "jobWcet": 789, + "numberOfJobs": 1, + "taskletWcet": 789, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 789, + "maximumParallelism": 1 + }, + { + "deadline": 967, + "period": 967, + "segments": [ + { + "jobWcet": 147, + "numberOfJobs": 1, + "taskletWcet": 147, + "numberOfTasklets": 1 + }, + { + "jobWcet": 10, + "numberOfJobs": 5, + "taskletWcet": 5, + "numberOfTasklets": 10 + }, + { + "jobWcet": 113, + "numberOfJobs": 1, + "taskletWcet": 113, + "numberOfTasklets": 1 + }, + { + "jobWcet": 21, + "numberOfJobs": 5, + "taskletWcet": 5, + "numberOfTasklets": 21 + } + ], + "maximumWcet": 415, + "maximumParallelism": 5 + } +] \ No newline at end of file diff --git a/src/test/resources/Taskset3.txt b/src/test/resources/Taskset3.txt new file mode 100644 index 0000000..2252691 --- /dev/null +++ b/src/test/resources/Taskset3.txt @@ -0,0 +1,86 @@ +[ + { + "deadline": 878, + "period": 878, + "segments": [ + { + "jobWcet": 33, + "numberOfJobs": 1, + "taskletWcet": 33, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 33, + "maximumParallelism": 1 + }, + { + "deadline": 641, + "period": 641, + "segments": [ + { + "jobWcet": 112, + "numberOfJobs": 1, + "taskletWcet": 112, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 112, + "maximumParallelism": 1 + }, + { + "deadline": 338, + "period": 338, + "segments": [ + { + "jobWcet": 251, + "numberOfJobs": 1, + "taskletWcet": 251, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 251, + "maximumParallelism": 1 + }, + { + "deadline": 645, + "period": 645, + "segments": [ + { + "jobWcet": 179, + "numberOfJobs": 1, + "taskletWcet": 179, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 179, + "maximumParallelism": 1 + }, + { + "deadline": 568, + "period": 568, + "segments": [ + { + "jobWcet": 332, + "numberOfJobs": 1, + "taskletWcet": 332, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 332, + "maximumParallelism": 1 + }, + { + "deadline": 493, + "period": 493, + "segments": [ + { + "jobWcet": 160, + "numberOfJobs": 1, + "taskletWcet": 160, + "numberOfTasklets": 1 + } + ], + "maximumWcet": 160, + "maximumParallelism": 1 + } +] \ No newline at end of file -- libgit2 0.26.0