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/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 extends TypeInterface> 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 extends AbstractTest> 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 extends AbstractSimulator> 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/PairInterface.java b/src/main/java/mvd/jester/TypeInterface.java
similarity index 85%
rename from src/main/java/mvd/jester/PairInterface.java
rename to src/main/java/mvd/jester/TypeInterface.java
index 393b0cf..66fd2d4 100644
--- a/src/main/java/mvd/jester/PairInterface.java
+++ b/src/main/java/mvd/jester/TypeInterface.java
@@ -3,9 +3,7 @@ package mvd.jester;
/**
* PairInterface
*/
-public interface 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 extends AbstractTest> abstractTestClass) {
+ return abstractTests.contains(abstractTestClass);
+ }
+
+ @Override
public boolean hasSimulator(AbstractSimulator abstractSimulator) {
return abstractSimulators.contains(abstractSimulator.getClass());
}
@Override
+ public boolean hasSimulator(Class extends AbstractSimulator> 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 extends AbstractTest> abstractTestClass);
+
public boolean hasSimulator(AbstractSimulator abstractTest);
+ public boolean hasSimulator(Class extends AbstractSimulator> 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 extends AbstractTest> abstractTestClass) {
+ return abstractTests.contains(abstractTestClass);
+ }
+
+ @Override
public boolean hasSimulator(AbstractSimulator abstractSimulator) {
return abstractSimulators.contains(abstractSimulator.getClass());
}
@Override
+ public boolean hasSimulator(Class extends AbstractSimulator> 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);
}
}