From d255848d16af10c4bac380fbdc4c3d4a0c156ddf Mon Sep 17 00:00:00 2001 From: Michael Schmid Date: Thu, 16 Jan 2020 15:20:46 +0100 Subject: [PATCH] Changed logging tools and added Chwa test --- pom.xml | 6 ++++++ src/main/java/mvd/jester/App.java | 17 ++++++++++++----- src/main/java/mvd/jester/Pair.java | 36 ------------------------------------ src/main/java/mvd/jester/PairInterface.java | 11 ----------- src/main/java/mvd/jester/ResultCollector.java | 196 +++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/main/java/mvd/jester/ResultLogger.java | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/mvd/jester/TestEnvironment.java | 71 ++++++++++++++++++++++++++--------------------------------------------- src/main/java/mvd/jester/TypeInterface.java | 9 +++++++++ src/main/java/mvd/jester/info/SchedulingInfo.java | 27 ++++++++++++++++++++++++--- src/main/java/mvd/jester/model/SystemSetup.java | 36 +++++++++++++++++++++++++----------- src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java | 18 +++++++++++++++--- src/main/java/mvd/jester/priority/PriorityManager.java | 4 ++++ src/main/java/mvd/jester/priority/RateMonotonic.java | 11 +++++++++++ src/main/java/mvd/jester/simulator/AbstractSimulator.java | 9 +++++---- src/main/java/mvd/jester/tests/AbstractTest.java | 4 ++-- src/main/java/mvd/jester/tests/ChwaLee.java | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/mvd/jester/tests/MaiaBertogna.java | 3 ++- src/main/java/mvd/jester/tests/SchmidMottok.java | 3 ++- src/main/java/mvd/jester/utils/Logger.java | 4 ++-- src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java | 3 +-- 20 files changed, 535 insertions(+), 289 deletions(-) delete mode 100644 src/main/java/mvd/jester/Pair.java delete mode 100644 src/main/java/mvd/jester/PairInterface.java create mode 100644 src/main/java/mvd/jester/ResultLogger.java create mode 100644 src/main/java/mvd/jester/TypeInterface.java create mode 100644 src/main/java/mvd/jester/tests/ChwaLee.java diff --git a/pom.xml b/pom.xml index b7c2801..5160f5d 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,12 @@ guava 28.0-jre + + + org.apache.commons + commons-csv + 1.7 + diff --git a/src/main/java/mvd/jester/App.java b/src/main/java/mvd/jester/App.java index ef9ab62..405fe01 100644 --- a/src/main/java/mvd/jester/App.java +++ b/src/main/java/mvd/jester/App.java @@ -3,6 +3,7 @@ package mvd.jester; import mvd.jester.model.SystemSetup; import mvd.jester.priority.EarliestDeadlineFirst; import mvd.jester.priority.RateMonotonic; +import mvd.jester.tests.ChwaLee; /** @@ -15,10 +16,11 @@ public class App { TestEnvironment te = new TestEnvironment(builder, 40000); te.registerSchedulingAlgorithm(new RateMonotonic()); - // te.registerSchedulingAlgorithm(new EarliestDeadlineFirst()); + te.registerSchedulingAlgorithm(new EarliestDeadlineFirst()); te.registerTest(mvd.jester.tests.SchmidMottok.class); te.registerTest(mvd.jester.tests.MaiaBertogna.class); + te.registerTest(mvd.jester.tests.ChwaLee.class); // te.registerSimulator(mvd.jester.simulator.MaiaBertogna.class); // te.registerSimulator(mvd.jester.simulator.SchmidMottok.class); @@ -26,9 +28,14 @@ public class App { te.runTests(); - // SystemSetup ss = builder.build(); - // builder.addTask(ss); - // builder.addTask(ss); - // ss.writeToFile("Test3.txt"); + // SystemSetup setup = SystemSetup.readFromFile( + // "/home/mike/Promotion/projects/eclipse/jester/results/test_this.txt", 16); + + // SchmidMottok sm = new SchmidMottok(setup); + // MaiaBertogna mb = new MaiaBertogna(setup); + // RateMonotonic rm = new RateMonotonic(); + + // sm.runSchedulabilityCheck(rm); + // mb.runSchedulabilityCheck(rm); } } diff --git a/src/main/java/mvd/jester/Pair.java b/src/main/java/mvd/jester/Pair.java deleted file mode 100644 index 828340a..0000000 --- a/src/main/java/mvd/jester/Pair.java +++ /dev/null @@ -1,36 +0,0 @@ -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 deleted file mode 100644 index 393b0cf..0000000 --- a/src/main/java/mvd/jester/PairInterface.java +++ /dev/null @@ -1,11 +0,0 @@ -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 index aad0549..658b41c 100644 --- a/src/main/java/mvd/jester/ResultCollector.java +++ b/src/main/java/mvd/jester/ResultCollector.java @@ -1,184 +1,54 @@ 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.HashSet; import java.util.Set; -import com.google.common.collect.Table; -import com.google.common.math.Stats; -import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; 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; +import mvd.jester.priority.PriorityManager; /** - * ResultCollector + * PriorityPair */ -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 class ResultCollector + implements Comparable> { + private final PriorityManager priorityManager; + private final T abstractValue; + private final Set schedulingInfos; + + public ResultCollector(PriorityManager priorityManager, T abstractValue) { + this.abstractValue = abstractValue; + this.priorityManager = priorityManager; + this.schedulingInfos = new HashSet<>(); } - public void logAll() { - if (!testResults.isEmpty()) { - logFeasibility(testResults, "test"); - logFeasibilityRatio(testResults, "test"); - logTardinessStatistics(testResults, "test"); - logFailedTardiness(testResults, "test"); - } - if (!simulatorResults.isEmpty()) { - logFeasibility(simulatorResults, "sim"); - logFeasibilityRatio(simulatorResults, "sim"); - logTardinessStatistics(simulatorResults, "sim"); - logFailedTardiness(simulatorResults, "sim"); - } + /** + * @return the priorityManager + */ + public PriorityManager getPriorityManager() { + return priorityManager; } - public void logFeasibilityRatio( - Table, Set> results, String type) { - LocalTime date = LocalTime.now(); - Logger log = new Logger("./results/feasibility_ratio_" + type + "_" + numberOfProcessors - + "_" + date.getHour() + ":" + date.getMinute() + ".txt"); - String firstLine = new String("Utilization"); - - 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); - for (Pair pair : results.columnKeySet()) { - long feasibleTasksets = results.get(util, pair).stream() - .filter(s -> s.checkTasksetFeasible()).count(); - line += "\t" + ((double) feasibleTasksets / totalNumberOfTasksets.get(util)); - } - log.log(line); - } - } - - log.finalize(); + /** + * @return the abstractValue + */ + public T getAbstractValue() { + return abstractValue; } - public void logFeasibility( - Table, Set> results, String type) { - LocalTime date = LocalTime.now(); - Logger log = new Logger("./results/feasibility_" + type + "_" + numberOfProcessors + "_" - + date.getHour() + ":" + date.getMinute() + ".txt"); - String firstLine = new String("Utilization"); - - 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); - 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 String getName() { + return abstractValue.getName() + "_" + priorityManager.getName(); } - 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"); - - 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); - 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 addResult(SchedulingInfo schedulingInfo) { + this.schedulingInfos.add(schedulingInfo); } - public void logTardinessStatistics( - Table, Set> results, String type) { - LocalTime date = LocalTime.now(); - Logger log = new Logger("./results/statistics_tardiness_" + type + "_" + numberOfProcessors - + "_" + date.getHour() + ":" + date.getMinute() + ".txt"); - String firstLine = new String("Utilization"); - - 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); - for (Pair pair : results.columnKeySet()) { - Set simulationInfos = results.get(kv, pair); - DescriptiveStatistics stats = new DescriptiveStatistics(); - - for (SchedulingInfo s : simulationInfos) { - for (TerminationInfo t : s.getTerminationInfos()) { - stats.addValue(t.getLateness()); - } - } - - line += "\t" + stats.getMean(); - } - log.log(line); - } - } - - log.finalize(); + public Set getResults() { + return schedulingInfos; } + @Override + public int compareTo(ResultCollector o) { + return getName().compareTo(o.getName()); + } } diff --git a/src/main/java/mvd/jester/ResultLogger.java b/src/main/java/mvd/jester/ResultLogger.java new file mode 100644 index 0000000..8db8cd9 --- /dev/null +++ b/src/main/java/mvd/jester/ResultLogger.java @@ -0,0 +1,226 @@ +package mvd.jester; + +import java.io.IOException; +import java.time.LocalTime; +import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Collectors; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ObjectArrays; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import mvd.jester.tests.AbstractTest; +import mvd.jester.utils.Logger; + +/** + * ResultCollector + */ +public class ResultLogger { + + private final long numberOfProcessors; + + public ResultLogger(long numberOfProcessors) { + this.numberOfProcessors = numberOfProcessors; + } + + // public void logAll() { + // if (!testResults.isEmpty()) { + // logFeasibility(testResults, "test"); + // logFeasibilityRatio(testResults, "test"); + // logTardinessStatistics(testResults, "test"); + // logFailedTardiness(testResults, "test"); + // } + // if (!simulatorResults.isEmpty()) { + // logFeasibility(simulatorResults, "sim"); + // logFeasibilityRatio(simulatorResults, "sim"); + // logTardinessStatistics(simulatorResults, "sim"); + // logFailedTardiness(simulatorResults, "sim"); + // } + // } + + public void logTests(Set> results) { + logFeasibility(results, "test"); + logTaskRatio(results, "test"); + } + + public void logFeasibility(Set> results, + String type) { + LocalTime date = LocalTime.now(); + Logger log = new Logger("./results/feasibility_" + type + "_" + numberOfProcessors + "_" + + date.getHour() + ":" + date.getMinute() + ".txt"); + + Table, Long> resultTable = TreeBasedTable.create(); + Set> resultCollectors = new TreeSet<>(); + + for (ResultCollector r : results) { + System.out.println(r.getName() + ": " + + r.getResults().stream().filter(p -> p.checkTasksetFeasible()).count()); + } + + for (long util = 0; util < numberOfProcessors * 10; util++) { + for (ResultCollector rc : results) { + resultCollectors.add(rc); + final long local_util = util; + long feasibleTasksets = rc.getResults().stream() + .filter(r -> Math.round(r.getUtilization() * 10) == local_util) + .filter(r -> r.checkTasksetFeasible()).count(); + resultTable.put(util, rc, feasibleTasksets); + } + } + + logData(log, resultTable, resultCollectors); + } + + public void logTaskRatio(Set> results, + String type) { + LocalTime date = LocalTime.now(); + Logger log = new Logger("./results/task_ratio_" + type + "_" + numberOfProcessors + "_" + + date.getHour() + ":" + date.getMinute() + ".txt"); + + Table, Long> resultTable = TreeBasedTable.create(); + Set> resultCollectors = new TreeSet<>(); + + for (long ratio = 0; ratio < 10; ratio += 1) { + for (ResultCollector rc : results) { + resultCollectors.add(rc); + final long local_ratio = ratio; + long feasibleTasksets = rc.getResults().stream() + .filter(r -> Math.round(r.getParallelTaskRatio() * 10) == local_ratio) + .filter(r -> r.checkTasksetFeasible()).count(); + resultTable.put(ratio, rc, feasibleTasksets); + } + } + + logData(log, resultTable, resultCollectors); + } + + private void logData(Logger log, + Table, Long> resultTable, + Set> resultCollectors) { + final Appendable out = new StringBuilder(); + try { + String[] resultCollectorNames = resultCollectors.stream() + .map(ResultCollector::getName).toArray(String[]::new); + String[] header = ObjectArrays.concat("Utilization", resultCollectorNames); + final CSVPrinter printer = CSVFormat.DEFAULT.withHeader(header).print(out); + + printer.printRecords(resultTable.rowMap().entrySet().stream() + .map(entry -> ImmutableList.builder().add((double) entry.getKey() / 10) + .addAll(entry.getValue().values()).build()) + .collect(Collectors.toList())); + } catch (final IOException e) { + e.printStackTrace(); + } + + log.log(out); + log.finalize(); + } + + + // public void logFeasibility( + // Table, Set> results, String type) { + // LocalTime date = LocalTime.now(); + // Logger log = new Logger("./results/feasibility_" + type + "_" + numberOfProcessors + "_" + // + date.getHour() + ":" + date.getMinute() + ".txt"); + // String firstLine = new String("Utilization"); + + // if (!results.isEmpty()) { + // for (ResultCollector pair : results.columnKeySet()) { + // firstLine = firstLine + "\t" + pair.getName(); + // } + + // log.log(firstLine); + + // for (Long util : totalNumberOfTasksets.keySet()) { + // String line = String.valueOf((double) util / 10); + // for (ResultCollector 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"); + + // if (!results.isEmpty()) { + // for (ResultCollector pair : results.columnKeySet()) { + // firstLine = firstLine + "\t" + pair.getName(); + // } + + // log.log(firstLine); + + // for (Long kv : totalNumberOfTasksets.keySet()) { + // String line = String.valueOf((double) kv / 10); + // for (ResultCollector 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 logTardinessStatistics( + // Table, Set> results, String type) { + // LocalTime date = LocalTime.now(); + // Logger log = new Logger("./results/statistics_tardiness_" + type + "_" + numberOfProcessors + // + "_" + date.getHour() + ":" + date.getMinute() + ".txt"); + // String firstLine = new String("Utilization"); + + // if (!results.isEmpty()) { + // for (ResultCollector pair : results.columnKeySet()) { + // firstLine = firstLine + "\t" + pair.getName(); + // } + + // log.log(firstLine); + + // for (Long kv : totalNumberOfTasksets.keySet()) { + // String line = String.valueOf((double) kv / 10); + // for (ResultCollector pair : results.columnKeySet()) { + // Set simulationInfos = results.get(kv, pair); + // DescriptiveStatistics stats = new DescriptiveStatistics(); + + // for (SchedulingInfo s : simulationInfos) { + // for (TerminationInfo t : s.getTerminationInfos()) { + // stats.addValue(t.getLateness()); + // } + // } + + // line += "\t" + stats.getMean(); + // } + // log.log(line); + // } + // } + + // log.finalize(); + // } + +} diff --git a/src/main/java/mvd/jester/TestEnvironment.java b/src/main/java/mvd/jester/TestEnvironment.java index 09c8464..0753155 100644 --- a/src/main/java/mvd/jester/TestEnvironment.java +++ b/src/main/java/mvd/jester/TestEnvironment.java @@ -1,12 +1,8 @@ package mvd.jester; import java.lang.reflect.Constructor; -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; @@ -78,31 +74,32 @@ public class TestEnvironment { } public void runTests() { - Set> abstractTestInstances = new HashSet<>(); - Set> abstractSimulatorInstances = new HashSet<>(); - - Map totalNumberOfTasksets = new HashMap<>(); - - Table, Set> testResults = HashBasedTable.create(); - Table, Set> simulatorResults = - HashBasedTable.create(); + Set> abstractTestInstances = new HashSet<>(); + Set> abstractSimulatorInstances = new HashSet<>(); for (PriorityManager pm : schedulingAlgorithms) { for (Constructor c : abstractTests) { try { - abstractTestInstances - .add(new Pair(pm, c.newInstance(this.systemSetup))); + if (pm.hasTest(c.getDeclaringClass())) { + abstractTestInstances.add(new ResultCollector(pm, + c.newInstance(this.systemSetup))); + } } catch (Exception e) { System.out.println("Could not instantiate object of AbstractTest!"); + throw new RuntimeException("Could not instantiate object of AbstractTest!"); } } for (Constructor c : abstractSimulators) { try { - abstractSimulatorInstances - .add(new Pair(pm, c.newInstance(this.systemSetup))); + if (pm.hasSimulator(c.getDeclaringClass())) { + abstractSimulatorInstances.add(new ResultCollector(pm, + c.newInstance(this.systemSetup))); + } } catch (Exception e) { System.out.println("Could not instantiate object of AbstractSimulator!"); + throw new RuntimeException( + "Could not instantiate object of AbstractSimulator!"); } } } @@ -119,41 +116,26 @@ public class TestEnvironment { checkedTasksets++; if (checkedTasksets % 100 == 0) { - System.out.println(checkedTasksets + " bereits geschafft"); + System.out.print(Math.round((double) checkedTasksets / numberOfTaskSets * 100) + + "% of " + numberOfTaskSets + " tasksets tested!\r"); } - long roundedUtilization = (long) (utilization * 10); - - totalNumberOfTasksets.compute(roundedUtilization, (k, v) -> v == null ? 1 : v + 1); - - for (Pair testInstance : abstractTestInstances) { + for (ResultCollector testInstance : abstractTestInstances) { PriorityManager priorityManager = testInstance.getPriorityManager(); AbstractTest abstractTest = testInstance.getAbstractValue(); - if (!testResults.contains(roundedUtilization, testInstance)) { - testResults.put(roundedUtilization, testInstance, new HashSet<>()); - } - if (priorityManager.hasTest(abstractTest)) { - SchedulingInfo schedulingInfo = - abstractTest.runSchedulabilityCheck(priorityManager); - testResults.get(roundedUtilization, testInstance).add(schedulingInfo); - } + SchedulingInfo schedulingInfo = + abstractTest.runSchedulabilityCheck(priorityManager); + testInstance.addResult(schedulingInfo); } - for (Pair simulatorInstance : abstractSimulatorInstances) { + for (ResultCollector simulatorInstance : abstractSimulatorInstances) { PriorityManager priorityManager = simulatorInstance.getPriorityManager(); AbstractSimulator abstractSimulator = simulatorInstance.getAbstractValue(); - if (!simulatorResults.contains(roundedUtilization, simulatorInstance)) { - simulatorResults.put(roundedUtilization, simulatorInstance, - new HashSet<>()); - } - if (priorityManager.hasSimulator(abstractSimulator)) { - SchedulingInfo schedulingInfo = - abstractSimulator.runSimulation(priorityManager); - simulatorResults.get(roundedUtilization, simulatorInstance) - .add(schedulingInfo); - } + SchedulingInfo schedulingInfo = + abstractSimulator.runSimulation(priorityManager); + simulatorInstance.addResult(schedulingInfo); } builder.addTask(systemSetup); @@ -161,11 +143,10 @@ public class TestEnvironment { utilization = this.systemSetup.getUtilization(); } } + System.out.println(""); + ResultLogger resultLogger = new ResultLogger(systemSetup.getNumberOfProcessors()); - ResultCollector resultCollector = new ResultCollector(testResults, simulatorResults, - totalNumberOfTasksets, systemSetup.getNumberOfProcessors()); - - resultCollector.logAll(); + resultLogger.logTests(abstractTestInstances); } } diff --git a/src/main/java/mvd/jester/TypeInterface.java b/src/main/java/mvd/jester/TypeInterface.java new file mode 100644 index 0000000..66fd2d4 --- /dev/null +++ b/src/main/java/mvd/jester/TypeInterface.java @@ -0,0 +1,9 @@ +package mvd.jester; + +/** + * PairInterface + */ +public interface TypeInterface { + public String getName(); +} + diff --git a/src/main/java/mvd/jester/info/SchedulingInfo.java b/src/main/java/mvd/jester/info/SchedulingInfo.java index bd7c772..adf6259 100644 --- a/src/main/java/mvd/jester/info/SchedulingInfo.java +++ b/src/main/java/mvd/jester/info/SchedulingInfo.java @@ -9,16 +9,37 @@ import java.util.Set; */ public class SchedulingInfo { + private final double parallelTaskRatio; + private final double utilization; private final Set terminationInfos; private Optional failedTerminationInfo; - public SchedulingInfo() { + public SchedulingInfo(double parallelTaskRatio, double utilization) { + this.parallelTaskRatio = parallelTaskRatio; + this.utilization = utilization; this.terminationInfos = new HashSet<>(); this.failedTerminationInfo = Optional.empty(); } - public SchedulingInfo(Set terminationInfos) { + /** + * @return the utilization + */ + public double getUtilization() { + return utilization; + } + + /** + * @return the parallelTaskRatio + */ + public double getParallelTaskRatio() { + return parallelTaskRatio; + } + + public SchedulingInfo(Set terminationInfos, double parallelTaskRatio, + double utilization) { this.terminationInfos = terminationInfos; + this.parallelTaskRatio = parallelTaskRatio; + this.utilization = utilization; failedTerminationInfo = terminationInfos.stream().filter(t -> t.getLateness() > 0).findFirst(); } @@ -46,7 +67,7 @@ public class SchedulingInfo { return failedTerminationInfo; } - public void setFailedTemrinationInfo(TerminationInfo failedTerminationInfo) { + public void setFailedTerminationInfo(TerminationInfo failedTerminationInfo) { this.failedTerminationInfo = Optional.of(failedTerminationInfo); } } diff --git a/src/main/java/mvd/jester/model/SystemSetup.java b/src/main/java/mvd/jester/model/SystemSetup.java index bbf4eae..9d344d6 100644 --- a/src/main/java/mvd/jester/model/SystemSetup.java +++ b/src/main/java/mvd/jester/model/SystemSetup.java @@ -51,6 +51,19 @@ public class SystemSetup { return utilization; } + + public double getParallelTaskRatio() { + long parallelTasks = 0; + + for (Task t : tasks) { + if (t.getMaximumParallelism() > 1) { + parallelTasks++; + } + } + + return (double) parallelTasks / tasks.size(); + } + @Override public String toString() { Gson gson = new GsonBuilder().setPrettyPrinting().create(); @@ -65,7 +78,7 @@ public class SystemSetup { } } - public static SystemSetup readFromFile(String path) { + public static SystemSetup readFromFile(String path, long numberOfProcessors) { String jsonString; try { byte[] encoded = Files.readAllBytes(Paths.get(path)); @@ -74,16 +87,16 @@ public class SystemSetup { System.out.println(e.getMessage()); jsonString = new String(""); } - return SystemSetup.fromString(jsonString); + return SystemSetup.fromString(jsonString, numberOfProcessors); } - public static SystemSetup fromString(String json) { + public static SystemSetup fromString(String json, long numberOfProcessors) { Gson gson = new GsonBuilder() .registerTypeAdapter(SortedTaskSet.class, new SortedTaskSet.Deserializer()) .create(); SortedTaskSet tasks = gson.fromJson(json, SortedTaskSet.class); - return new SystemSetup(tasks, 8); + return new SystemSetup(tasks, numberOfProcessors); } public static class Builder { @@ -95,7 +108,8 @@ public class SystemSetup { private long minNumberOfJobs = 2; private long maxNumberOfJobs = 3 * numberOfProcessors / 2; private long minWcet = 1; - private long ratio = randomTaskRatio(); + private long ratio = randomTaskRatio(this.parallelTaskRatio); + private long parallelTaskRatio = 0; public Builder() { @@ -105,11 +119,11 @@ public class SystemSetup { if (serial) return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod); else - return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod * 10); + return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod /* * 10 */); } - private long randomTaskRatio() { - return ThreadLocalRandom.current().nextLong(0, 100); + private long randomTaskRatio(long min) { + return ThreadLocalRandom.current().nextLong(min, 100); } private long randomNumberOfSegments() { @@ -128,7 +142,7 @@ public class SystemSetup { } private Task generateTask() { - boolean serial = randomTaskRatio() > this.ratio; + boolean serial = randomTaskRatio(0) > this.ratio; long period = randomTaskPeriod(serial); long numberOfSegments = serial ? 1 : randomNumberOfSegments(); long parallelNumberOfJobs = serial ? 1 : randomNumberOfJobs(); @@ -154,13 +168,13 @@ public class SystemSetup { } public SystemSetup build() { - this.ratio = randomTaskRatio(); + this.ratio = randomTaskRatio(this.parallelTaskRatio); Set taskSet = generateTaskSet(); return new SystemSetup(taskSet, numberOfProcessors); } public void rebuild(SystemSetup systemSetup) { - this.ratio = randomTaskRatio(); + this.ratio = randomTaskRatio(this.parallelTaskRatio); systemSetup.tasks = generateTaskSet(); } diff --git a/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java b/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java index 4cb4116..4af7fa2 100644 --- a/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java +++ b/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java @@ -9,13 +9,15 @@ import mvd.jester.simulator.MaiaBertogna; import mvd.jester.simulator.SchmidMottok; import mvd.jester.simulator.internals.TaskContextInterface; import mvd.jester.tests.AbstractTest; +import mvd.jester.tests.ChwaLee; /** * EarliestDeadineFirst */ public class EarliestDeadlineFirst implements PriorityManager { - final static Set> abstractTests = new HashSet<>(); + final static Set> abstractTests = + new HashSet<>(Arrays.asList(ChwaLee.class)); final static Set> abstractSimulators = new HashSet<>(Arrays.asList(MaiaBertogna.class, SchmidMottok.class)); @@ -29,8 +31,7 @@ public class EarliestDeadlineFirst implements PriorityManager { */ @Override public int compare(Task t1, Task t2) { - throw new RuntimeException( - "Earliest Deadline First does not have Priority Manager for tasks"); + return (int) (t1.getDeadline() - t2.getDeadline()); } @Override @@ -44,12 +45,23 @@ public class EarliestDeadlineFirst implements PriorityManager { } @Override + public boolean hasTest(Class abstractTestClass) { + return abstractTests.contains(abstractTestClass); + } + + @Override public boolean hasSimulator(AbstractSimulator abstractSimulator) { return abstractSimulators.contains(abstractSimulator.getClass()); } @Override + public boolean hasSimulator(Class abstractSimulatorClass) { + return abstractSimulators.contains(abstractSimulatorClass); + } + + @Override public String getName() { return "EDF"; } + } diff --git a/src/main/java/mvd/jester/priority/PriorityManager.java b/src/main/java/mvd/jester/priority/PriorityManager.java index 5815d77..ffa84bf 100644 --- a/src/main/java/mvd/jester/priority/PriorityManager.java +++ b/src/main/java/mvd/jester/priority/PriorityManager.java @@ -16,8 +16,12 @@ public interface PriorityManager { public boolean hasTest(AbstractTest abstractTest); + public boolean hasTest(Class abstractTestClass); + public boolean hasSimulator(AbstractSimulator abstractTest); + public boolean hasSimulator(Class abstractTestClass); + public String getName(); } diff --git a/src/main/java/mvd/jester/priority/RateMonotonic.java b/src/main/java/mvd/jester/priority/RateMonotonic.java index 4698e3e..b76a947 100644 --- a/src/main/java/mvd/jester/priority/RateMonotonic.java +++ b/src/main/java/mvd/jester/priority/RateMonotonic.java @@ -40,13 +40,24 @@ public class RateMonotonic implements PriorityManager { } @Override + public boolean hasTest(Class abstractTestClass) { + return abstractTests.contains(abstractTestClass); + } + + @Override public boolean hasSimulator(AbstractSimulator abstractSimulator) { return abstractSimulators.contains(abstractSimulator.getClass()); } @Override + public boolean hasSimulator(Class abstractSimulatorClass) { + return abstractSimulators.contains(abstractSimulatorClass); + } + + @Override public String getName() { return "RM"; } + } diff --git a/src/main/java/mvd/jester/simulator/AbstractSimulator.java b/src/main/java/mvd/jester/simulator/AbstractSimulator.java index 6a7e9d7..a019dae 100644 --- a/src/main/java/mvd/jester/simulator/AbstractSimulator.java +++ b/src/main/java/mvd/jester/simulator/AbstractSimulator.java @@ -10,7 +10,7 @@ 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.TypeInterface; import mvd.jester.info.SchedulingInfo; import mvd.jester.info.TerminationInfo; import mvd.jester.simulator.internals.ProcessorContext; @@ -20,7 +20,7 @@ import mvd.jester.simulator.internals.TaskContextInterface; /** * AbstractSimulator */ -public abstract class AbstractSimulator implements SimulatorInterface, PairInterface { +public abstract class AbstractSimulator implements SimulatorInterface, TypeInterface { protected final SystemSetup systemSetup; protected final Set processors; @@ -43,7 +43,8 @@ public abstract class AbstractSimulator implements SimulatorInterface, PairInter @Override public SchedulingInfo runSimulation(PriorityManager priorityManager) { - SchedulingInfo schedulingInfo = new SchedulingInfo(); + SchedulingInfo schedulingInfo = new SchedulingInfo(systemSetup.getParallelTaskRatio(), + systemSetup.getUtilization()); init(priorityManager); for (int t = 0; t < hyperPeriod; ++t) { if (!releaseTasks(t)) { @@ -70,7 +71,7 @@ public abstract class AbstractSimulator implements SimulatorInterface, PairInter schedulingInfo.addTerminationInfo(terminationInfo); if (t >= tc.getDeadline()) { EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!"); - schedulingInfo.setFailedTemrinationInfo(terminationInfo); + schedulingInfo.setFailedTerminationInfo(terminationInfo); return schedulingInfo; } diff --git a/src/main/java/mvd/jester/tests/AbstractTest.java b/src/main/java/mvd/jester/tests/AbstractTest.java index 32335a2..d8cd647 100644 --- a/src/main/java/mvd/jester/tests/AbstractTest.java +++ b/src/main/java/mvd/jester/tests/AbstractTest.java @@ -3,7 +3,7 @@ package mvd.jester.tests; import java.util.HashMap; import java.util.Map; import java.util.Set; -import mvd.jester.PairInterface; +import mvd.jester.TypeInterface; import mvd.jester.info.TerminationInfo; import mvd.jester.model.SystemSetup; import mvd.jester.model.Task; @@ -11,7 +11,7 @@ import mvd.jester.model.Task; /** * AbstractTest */ -public abstract class AbstractTest implements TestInterface, PairInterface { +public abstract class AbstractTest implements TestInterface, TypeInterface { protected final Map responseTimes; protected final SystemSetup systemSetup; diff --git a/src/main/java/mvd/jester/tests/ChwaLee.java b/src/main/java/mvd/jester/tests/ChwaLee.java new file mode 100644 index 0000000..e3bb107 --- /dev/null +++ b/src/main/java/mvd/jester/tests/ChwaLee.java @@ -0,0 +1,130 @@ +package mvd.jester.tests; + +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +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.SystemSetup; +import mvd.jester.model.Task; +import mvd.jester.priority.PriorityManager; + +/** + * ChwaLee + */ +public class ChwaLee extends AbstractTest { + + public ChwaLee(SystemSetup systemSetup) { + super(systemSetup); + } + + @Override + public SchedulingInfo runSchedulabilityCheck(PriorityManager priorityManager) { + tasks = new SortedTaskSet(priorityManager); + tasks.addAll(systemSetup.getTasks()); + responseTimes.clear(); + for (Task t : tasks) { + long responseTime = calculateResponseTime(t); + responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); + } + + return new SchedulingInfo(new HashSet<>(responseTimes.values()), + systemSetup.getParallelTaskRatio(), systemSetup.getUtilization()); + } + + private long calculateResponseTime(Task task) { + long minimumWcet = getMinimumWcet(task); + long deadline = task.getDeadline(); + long numberOfProcessors = systemSetup.getNumberOfProcessors(); + + long taskInterference = 0; + + for (Task t : tasks) { + if (!t.equals(task)) { + long maxNumberOfJobs = t.getMaximumParallelism(); + for (long p = 0; p < maxNumberOfJobs; ++p) { + taskInterference += Math.min(getTaskInterference(t, deadline, p + 1), + deadline - minimumWcet); + } + } + } + + long selfInterference = 0; + + long maxNumberOfJobs = task.getMaximumParallelism(); + + for (long p = 0; p < maxNumberOfJobs; ++p) { + selfInterference += + Math.min(getSelfInterference(task, deadline, p + 1), deadline - minimumWcet); + } + + boolean feasible = taskInterference + selfInterference <= numberOfProcessors + * (deadline - minimumWcet); + + return feasible ? deadline - 1 : deadline + 1; + } + + private long getSelfInterference(Task task, long deadline, long p) { + long selfInterference = 0; + + for (Segment s : task.getSegments()) { + if (s.getNumberOfJobs() >= p + 1) { + selfInterference += s.getJobWcet(); + } + } + return selfInterference; + } + + private long getTaskInterference(Task t, long deadline, long p) { + long numberOfBodyJobs = LongMath.divide(deadline, t.getPeriod(), RoundingMode.FLOOR); + + long workloadOfBodyJobs = 0; + + for (Segment s : t.getSegments()) { + if (s.getNumberOfJobs() >= p) { + workloadOfBodyJobs += s.getJobWcet(); + } + } + + long boundedBodyWorkload = numberOfBodyJobs * workloadOfBodyJobs; + long boundedCarryInWorkload = 0; + long remainingLength = deadline % t.getPeriod(); + long carryInLength = 0; + List segmentList = new ArrayList<>(t.getSegments()); + Collections.reverse(segmentList); + for (Segment s : segmentList) { + carryInLength += s.getJobWcet(); + if (s.getNumberOfJobs() >= p && remainingLength > carryInLength) { + boundedCarryInWorkload += s.getJobWcet(); + } else if (s.getNumberOfJobs() >= p && remainingLength <= carryInLength) { + boundedCarryInWorkload += s.getJobWcet() - (carryInLength - remainingLength); + } + if (carryInLength >= remainingLength) { + break; + } + } + + return boundedBodyWorkload + boundedCarryInWorkload; + } + + private long getMinimumWcet(Task task) { + long minWcet = 0; + for (Segment s : task.getSegments()) { + minWcet += s.getJobWcet(); + } + + return minWcet; + } + + @Override + public String getName() { + return "ChwaLee"; + } + + +} diff --git a/src/main/java/mvd/jester/tests/MaiaBertogna.java b/src/main/java/mvd/jester/tests/MaiaBertogna.java index 353a929..0b29619 100644 --- a/src/main/java/mvd/jester/tests/MaiaBertogna.java +++ b/src/main/java/mvd/jester/tests/MaiaBertogna.java @@ -30,7 +30,8 @@ public class MaiaBertogna extends AbstractTest { responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); } - return new SchedulingInfo(new HashSet<>(responseTimes.values())); + return new SchedulingInfo(new HashSet<>(responseTimes.values()), + systemSetup.getParallelTaskRatio(), systemSetup.getUtilization()); } @Override diff --git a/src/main/java/mvd/jester/tests/SchmidMottok.java b/src/main/java/mvd/jester/tests/SchmidMottok.java index a43f38a..edc0a1a 100644 --- a/src/main/java/mvd/jester/tests/SchmidMottok.java +++ b/src/main/java/mvd/jester/tests/SchmidMottok.java @@ -30,7 +30,8 @@ public class SchmidMottok extends AbstractTest { responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); } - return new SchedulingInfo(new HashSet<>(responseTimes.values())); + return new SchedulingInfo(new HashSet<>(responseTimes.values()), + systemSetup.getParallelTaskRatio(), systemSetup.getUtilization()); } @Override diff --git a/src/main/java/mvd/jester/utils/Logger.java b/src/main/java/mvd/jester/utils/Logger.java index 4ed0e93..f82b9e2 100644 --- a/src/main/java/mvd/jester/utils/Logger.java +++ b/src/main/java/mvd/jester/utils/Logger.java @@ -24,8 +24,8 @@ public class Logger { } - public void log(String line) { - printWriter.println(line); + public void log(Appendable sb) { + printWriter.write(sb.toString()); } public void finalize() { diff --git a/src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java b/src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java index 7dd23d7..dee0483 100644 --- a/src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java +++ b/src/test/java/mvd/jester/priority/TestEarliestDeadlineFirst.java @@ -1,6 +1,5 @@ package mvd.jester.priority; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.HashSet; import org.junit.jupiter.api.DisplayName; @@ -23,7 +22,7 @@ public class TestEarliestDeadlineFirst { TaskContext tc1 = new TaskContext(t1, 0); TaskContext tc2 = new TaskContext(t2, 0); - assertThrows(RuntimeException.class, () -> edf.compare(t1, t2)); + assertTrue(edf.compare(t1, t2) < 0); assertTrue(edf.compare(tc1, tc2) < 0); } } -- libgit2 0.26.0