Commit d255848d by Michael Schmid

Changed logging tools and added Chwa test

parent 402173ef
...@@ -48,6 +48,12 @@ ...@@ -48,6 +48,12 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>28.0-jre</version> <version>28.0-jre</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.7</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -3,6 +3,7 @@ package mvd.jester; ...@@ -3,6 +3,7 @@ package mvd.jester;
import mvd.jester.model.SystemSetup; import mvd.jester.model.SystemSetup;
import mvd.jester.priority.EarliestDeadlineFirst; import mvd.jester.priority.EarliestDeadlineFirst;
import mvd.jester.priority.RateMonotonic; import mvd.jester.priority.RateMonotonic;
import mvd.jester.tests.ChwaLee;
/** /**
...@@ -15,10 +16,11 @@ public class App { ...@@ -15,10 +16,11 @@ public class App {
TestEnvironment te = new TestEnvironment(builder, 40000); TestEnvironment te = new TestEnvironment(builder, 40000);
te.registerSchedulingAlgorithm(new RateMonotonic()); te.registerSchedulingAlgorithm(new RateMonotonic());
// te.registerSchedulingAlgorithm(new EarliestDeadlineFirst()); te.registerSchedulingAlgorithm(new EarliestDeadlineFirst());
te.registerTest(mvd.jester.tests.SchmidMottok.class); te.registerTest(mvd.jester.tests.SchmidMottok.class);
te.registerTest(mvd.jester.tests.MaiaBertogna.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.MaiaBertogna.class);
// te.registerSimulator(mvd.jester.simulator.SchmidMottok.class); // te.registerSimulator(mvd.jester.simulator.SchmidMottok.class);
...@@ -26,9 +28,14 @@ public class App { ...@@ -26,9 +28,14 @@ public class App {
te.runTests(); te.runTests();
// SystemSetup ss = builder.build(); // SystemSetup setup = SystemSetup.readFromFile(
// builder.addTask(ss); // "/home/mike/Promotion/projects/eclipse/jester/results/test_this.txt", 16);
// builder.addTask(ss);
// ss.writeToFile("Test3.txt"); // SchmidMottok sm = new SchmidMottok(setup);
// MaiaBertogna mb = new MaiaBertogna(setup);
// RateMonotonic rm = new RateMonotonic();
// sm.runSchedulabilityCheck(rm);
// mb.runSchedulabilityCheck(rm);
} }
} }
package mvd.jester;
import mvd.jester.priority.PriorityManager;
/**
* PriorityPair
*/
public class Pair<T extends PairInterface> {
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();
}
}
package mvd.jester; package mvd.jester;
import java.time.LocalTime; import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set; 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.SchedulingInfo;
import mvd.jester.info.TerminationInfo; import mvd.jester.priority.PriorityManager;
import mvd.jester.simulator.AbstractSimulator;
import mvd.jester.tests.AbstractTest;
import mvd.jester.utils.Logger;
/** /**
* ResultCollector * PriorityPair
*/ */
public class ResultCollector { public class ResultCollector<T extends TypeInterface>
implements Comparable<ResultCollector<? extends TypeInterface>> {
private final Table<Long, Pair<AbstractTest>, Set<SchedulingInfo>> testResults; private final PriorityManager priorityManager;
private final Table<Long, Pair<AbstractSimulator>, Set<SchedulingInfo>> simulatorResults; private final T abstractValue;
private final Map<Long, Long> totalNumberOfTasksets; private final Set<SchedulingInfo> schedulingInfos;
private final long numberOfProcessors;
public ResultCollector(PriorityManager priorityManager, T abstractValue) {
public ResultCollector(Table<Long, Pair<AbstractTest>, Set<SchedulingInfo>> testResults, this.abstractValue = abstractValue;
Table<Long, Pair<AbstractSimulator>, Set<SchedulingInfo>> simulatorResults, this.priorityManager = priorityManager;
Map<Long, Long> totalNumberOfTasksets, long numberOfProcessors) { this.schedulingInfos = new HashSet<>();
this.testResults = testResults;
this.simulatorResults = simulatorResults;
this.totalNumberOfTasksets = totalNumberOfTasksets;
this.numberOfProcessors = numberOfProcessors;
} }
public void logAll() { /**
if (!testResults.isEmpty()) { * @return the priorityManager
logFeasibility(testResults, "test"); */
logFeasibilityRatio(testResults, "test"); public PriorityManager getPriorityManager() {
logTardinessStatistics(testResults, "test"); return priorityManager;
logFailedTardiness(testResults, "test");
}
if (!simulatorResults.isEmpty()) {
logFeasibility(simulatorResults, "sim");
logFeasibilityRatio(simulatorResults, "sim");
logTardinessStatistics(simulatorResults, "sim");
logFailedTardiness(simulatorResults, "sim");
}
} }
public <T extends PairInterface> void logFeasibilityRatio( /**
Table<Long, Pair<T>, Set<SchedulingInfo>> results, String type) { * @return the abstractValue
LocalTime date = LocalTime.now(); */
Logger log = new Logger("./results/feasibility_ratio_" + type + "_" + numberOfProcessors public T getAbstractValue() {
+ "_" + date.getHour() + ":" + date.getMinute() + ".txt"); return abstractValue;
String firstLine = new String("Utilization");
if (!results.isEmpty()) {
for (Pair<T> 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<T> 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();
} }
public <T extends PairInterface> void logFeasibility( public String getName() {
Table<Long, Pair<T>, Set<SchedulingInfo>> results, String type) { return abstractValue.getName() + "_" + priorityManager.getName();
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<T> 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<T> pair : results.columnKeySet()) {
long feasibleTasksets = results.get(util, pair).stream()
.filter(s -> s.checkTasksetFeasible()).count();
line += "\t" + feasibleTasksets;
}
log.log(line);
}
}
log.finalize();
} }
public <T extends PairInterface> void logFailedTardiness( public void addResult(SchedulingInfo schedulingInfo) {
Table<Long, Pair<T>, Set<SchedulingInfo>> results, String type) { this.schedulingInfos.add(schedulingInfo);
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<T> 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<T> pair : results.columnKeySet()) {
Set<SchedulingInfo> simulationInfos = results.get(kv, pair);
List<Long> values = new ArrayList<>();
for (SchedulingInfo s : simulationInfos) {
Optional<TerminationInfo> 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 <T extends PairInterface> void logTardinessStatistics( public Set<SchedulingInfo> getResults() {
Table<Long, Pair<T>, Set<SchedulingInfo>> results, String type) { return schedulingInfos;
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<T> 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<T> pair : results.columnKeySet()) {
Set<SchedulingInfo> 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();
} }
@Override
public int compareTo(ResultCollector<? extends TypeInterface> o) {
return getName().compareTo(o.getName());
}
} }
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<ResultCollector<AbstractTest>> results) {
logFeasibility(results, "test");
logTaskRatio(results, "test");
}
public <T extends TypeInterface> void logFeasibility(Set<ResultCollector<T>> results,
String type) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/feasibility_" + type + "_" + numberOfProcessors + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
Table<Long, ResultCollector<T>, Long> resultTable = TreeBasedTable.create();
Set<ResultCollector<T>> resultCollectors = new TreeSet<>();
for (ResultCollector<T> 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<T> 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 <T extends TypeInterface> void logTaskRatio(Set<ResultCollector<T>> results,
String type) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/task_ratio_" + type + "_" + numberOfProcessors + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
Table<Long, ResultCollector<T>, Long> resultTable = TreeBasedTable.create();
Set<ResultCollector<T>> resultCollectors = new TreeSet<>();
for (long ratio = 0; ratio < 10; ratio += 1) {
for (ResultCollector<T> 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 <T extends TypeInterface> void logData(Logger log,
Table<Long, ResultCollector<T>, Long> resultTable,
Set<ResultCollector<T>> resultCollectors) {
final Appendable out = new StringBuilder();
try {
String[] resultCollectorNames = resultCollectors.stream()
.map(ResultCollector<T>::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 <T extends TypeInterface> void logFeasibility(
// Table<Long, ResultCollector<T>, Set<SchedulingInfo>> 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<T> 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<T> pair : results.columnKeySet()) {
// long feasibleTasksets = results.get(util, pair).stream()
// .filter(s -> s.checkTasksetFeasible()).count();
// line += "\t" + feasibleTasksets;
// }
// log.log(line);
// }
// }
// log.finalize();
// }
// public <T extends TypeInterface> void logFailedTardiness(
// Table<Long, ResultCollector<T>, Set<SchedulingInfo>> 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<T> 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<T> pair : results.columnKeySet()) {
// Set<SchedulingInfo> simulationInfos = results.get(kv, pair);
// List<Long> values = new ArrayList<>();
// for (SchedulingInfo s : simulationInfos) {
// Optional<TerminationInfo> 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 <T extends TypeInterface> void logTardinessStatistics(
// Table<Long, ResultCollector<T>, Set<SchedulingInfo>> 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<T> 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<T> pair : results.columnKeySet()) {
// Set<SchedulingInfo> 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();
// }
}
package mvd.jester; package mvd.jester;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import mvd.jester.info.SchedulingInfo; import mvd.jester.info.SchedulingInfo;
import mvd.jester.model.SystemSetup; import mvd.jester.model.SystemSetup;
import mvd.jester.priority.PriorityManager; import mvd.jester.priority.PriorityManager;
...@@ -78,31 +74,32 @@ public class TestEnvironment { ...@@ -78,31 +74,32 @@ public class TestEnvironment {
} }
public void runTests() { public void runTests() {
Set<Pair<AbstractTest>> abstractTestInstances = new HashSet<>(); Set<ResultCollector<AbstractTest>> abstractTestInstances = new HashSet<>();
Set<Pair<AbstractSimulator>> abstractSimulatorInstances = new HashSet<>(); Set<ResultCollector<AbstractSimulator>> abstractSimulatorInstances = new HashSet<>();
Map<Long, Long> totalNumberOfTasksets = new HashMap<>();
Table<Long, Pair<AbstractTest>, Set<SchedulingInfo>> testResults = HashBasedTable.create();
Table<Long, Pair<AbstractSimulator>, Set<SchedulingInfo>> simulatorResults =
HashBasedTable.create();
for (PriorityManager pm : schedulingAlgorithms) { for (PriorityManager pm : schedulingAlgorithms) {
for (Constructor<? extends AbstractTest> c : abstractTests) { for (Constructor<? extends AbstractTest> c : abstractTests) {
try { try {
abstractTestInstances if (pm.hasTest(c.getDeclaringClass())) {
.add(new Pair<AbstractTest>(pm, c.newInstance(this.systemSetup))); abstractTestInstances.add(new ResultCollector<AbstractTest>(pm,
c.newInstance(this.systemSetup)));
}
} catch (Exception e) { } catch (Exception e) {
System.out.println("Could not instantiate object of AbstractTest!"); System.out.println("Could not instantiate object of AbstractTest!");
throw new RuntimeException("Could not instantiate object of AbstractTest!");
} }
} }
for (Constructor<? extends AbstractSimulator> c : abstractSimulators) { for (Constructor<? extends AbstractSimulator> c : abstractSimulators) {
try { try {
abstractSimulatorInstances if (pm.hasSimulator(c.getDeclaringClass())) {
.add(new Pair<AbstractSimulator>(pm, c.newInstance(this.systemSetup))); abstractSimulatorInstances.add(new ResultCollector<AbstractSimulator>(pm,
c.newInstance(this.systemSetup)));
}
} catch (Exception e) { } catch (Exception e) {
System.out.println("Could not instantiate object of AbstractSimulator!"); 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 { ...@@ -119,41 +116,26 @@ public class TestEnvironment {
checkedTasksets++; checkedTasksets++;
if (checkedTasksets % 100 == 0) { 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); for (ResultCollector<AbstractTest> testInstance : abstractTestInstances) {
totalNumberOfTasksets.compute(roundedUtilization, (k, v) -> v == null ? 1 : v + 1);
for (Pair<AbstractTest> testInstance : abstractTestInstances) {
PriorityManager priorityManager = testInstance.getPriorityManager(); PriorityManager priorityManager = testInstance.getPriorityManager();
AbstractTest abstractTest = testInstance.getAbstractValue(); AbstractTest abstractTest = testInstance.getAbstractValue();
if (!testResults.contains(roundedUtilization, testInstance)) {
testResults.put(roundedUtilization, testInstance, new HashSet<>());
}
if (priorityManager.hasTest(abstractTest)) { SchedulingInfo schedulingInfo =
SchedulingInfo schedulingInfo = abstractTest.runSchedulabilityCheck(priorityManager);
abstractTest.runSchedulabilityCheck(priorityManager); testInstance.addResult(schedulingInfo);
testResults.get(roundedUtilization, testInstance).add(schedulingInfo);
}
} }
for (Pair<AbstractSimulator> simulatorInstance : abstractSimulatorInstances) { for (ResultCollector<AbstractSimulator> simulatorInstance : abstractSimulatorInstances) {
PriorityManager priorityManager = simulatorInstance.getPriorityManager(); PriorityManager priorityManager = simulatorInstance.getPriorityManager();
AbstractSimulator abstractSimulator = simulatorInstance.getAbstractValue(); AbstractSimulator abstractSimulator = simulatorInstance.getAbstractValue();
if (!simulatorResults.contains(roundedUtilization, simulatorInstance)) {
simulatorResults.put(roundedUtilization, simulatorInstance,
new HashSet<>());
}
if (priorityManager.hasSimulator(abstractSimulator)) { SchedulingInfo schedulingInfo =
SchedulingInfo schedulingInfo = abstractSimulator.runSimulation(priorityManager);
abstractSimulator.runSimulation(priorityManager); simulatorInstance.addResult(schedulingInfo);
simulatorResults.get(roundedUtilization, simulatorInstance)
.add(schedulingInfo);
}
} }
builder.addTask(systemSetup); builder.addTask(systemSetup);
...@@ -161,11 +143,10 @@ public class TestEnvironment { ...@@ -161,11 +143,10 @@ public class TestEnvironment {
utilization = this.systemSetup.getUtilization(); utilization = this.systemSetup.getUtilization();
} }
} }
System.out.println("");
ResultLogger resultLogger = new ResultLogger(systemSetup.getNumberOfProcessors());
ResultCollector resultCollector = new ResultCollector(testResults, simulatorResults, resultLogger.logTests(abstractTestInstances);
totalNumberOfTasksets, systemSetup.getNumberOfProcessors());
resultCollector.logAll();
} }
} }
......
...@@ -3,9 +3,7 @@ package mvd.jester; ...@@ -3,9 +3,7 @@ package mvd.jester;
/** /**
* PairInterface * PairInterface
*/ */
public interface PairInterface { public interface TypeInterface {
public String getName(); public String getName();
} }
...@@ -9,16 +9,37 @@ import java.util.Set; ...@@ -9,16 +9,37 @@ import java.util.Set;
*/ */
public class SchedulingInfo { public class SchedulingInfo {
private final double parallelTaskRatio;
private final double utilization;
private final Set<TerminationInfo> terminationInfos; private final Set<TerminationInfo> terminationInfos;
private Optional<TerminationInfo> failedTerminationInfo; private Optional<TerminationInfo> failedTerminationInfo;
public SchedulingInfo() { public SchedulingInfo(double parallelTaskRatio, double utilization) {
this.parallelTaskRatio = parallelTaskRatio;
this.utilization = utilization;
this.terminationInfos = new HashSet<>(); this.terminationInfos = new HashSet<>();
this.failedTerminationInfo = Optional.empty(); this.failedTerminationInfo = Optional.empty();
} }
public SchedulingInfo(Set<TerminationInfo> terminationInfos) { /**
* @return the utilization
*/
public double getUtilization() {
return utilization;
}
/**
* @return the parallelTaskRatio
*/
public double getParallelTaskRatio() {
return parallelTaskRatio;
}
public SchedulingInfo(Set<TerminationInfo> terminationInfos, double parallelTaskRatio,
double utilization) {
this.terminationInfos = terminationInfos; this.terminationInfos = terminationInfos;
this.parallelTaskRatio = parallelTaskRatio;
this.utilization = utilization;
failedTerminationInfo = failedTerminationInfo =
terminationInfos.stream().filter(t -> t.getLateness() > 0).findFirst(); terminationInfos.stream().filter(t -> t.getLateness() > 0).findFirst();
} }
...@@ -46,7 +67,7 @@ public class SchedulingInfo { ...@@ -46,7 +67,7 @@ public class SchedulingInfo {
return failedTerminationInfo; return failedTerminationInfo;
} }
public void setFailedTemrinationInfo(TerminationInfo failedTerminationInfo) { public void setFailedTerminationInfo(TerminationInfo failedTerminationInfo) {
this.failedTerminationInfo = Optional.of(failedTerminationInfo); this.failedTerminationInfo = Optional.of(failedTerminationInfo);
} }
} }
...@@ -51,6 +51,19 @@ public class SystemSetup { ...@@ -51,6 +51,19 @@ public class SystemSetup {
return utilization; return utilization;
} }
public double getParallelTaskRatio() {
long parallelTasks = 0;
for (Task t : tasks) {
if (t.getMaximumParallelism() > 1) {
parallelTasks++;
}
}
return (double) parallelTasks / tasks.size();
}
@Override @Override
public String toString() { public String toString() {
Gson gson = new GsonBuilder().setPrettyPrinting().create(); Gson gson = new GsonBuilder().setPrettyPrinting().create();
...@@ -65,7 +78,7 @@ public class SystemSetup { ...@@ -65,7 +78,7 @@ public class SystemSetup {
} }
} }
public static SystemSetup readFromFile(String path) { public static SystemSetup readFromFile(String path, long numberOfProcessors) {
String jsonString; String jsonString;
try { try {
byte[] encoded = Files.readAllBytes(Paths.get(path)); byte[] encoded = Files.readAllBytes(Paths.get(path));
...@@ -74,16 +87,16 @@ public class SystemSetup { ...@@ -74,16 +87,16 @@ public class SystemSetup {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
jsonString = new String(""); 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() Gson gson = new GsonBuilder()
.registerTypeAdapter(SortedTaskSet.class, new SortedTaskSet.Deserializer()) .registerTypeAdapter(SortedTaskSet.class, new SortedTaskSet.Deserializer())
.create(); .create();
SortedTaskSet tasks = gson.fromJson(json, SortedTaskSet.class); SortedTaskSet tasks = gson.fromJson(json, SortedTaskSet.class);
return new SystemSetup(tasks, 8); return new SystemSetup(tasks, numberOfProcessors);
} }
public static class Builder { public static class Builder {
...@@ -95,7 +108,8 @@ public class SystemSetup { ...@@ -95,7 +108,8 @@ public class SystemSetup {
private long minNumberOfJobs = 2; private long minNumberOfJobs = 2;
private long maxNumberOfJobs = 3 * numberOfProcessors / 2; private long maxNumberOfJobs = 3 * numberOfProcessors / 2;
private long minWcet = 1; private long minWcet = 1;
private long ratio = randomTaskRatio(); private long ratio = randomTaskRatio(this.parallelTaskRatio);
private long parallelTaskRatio = 0;
public Builder() { public Builder() {
...@@ -105,11 +119,11 @@ public class SystemSetup { ...@@ -105,11 +119,11 @@ public class SystemSetup {
if (serial) if (serial)
return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod); return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod);
else else
return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod * 10); return ThreadLocalRandom.current().nextLong(minPeriod, maxPeriod /* * 10 */);
} }
private long randomTaskRatio() { private long randomTaskRatio(long min) {
return ThreadLocalRandom.current().nextLong(0, 100); return ThreadLocalRandom.current().nextLong(min, 100);
} }
private long randomNumberOfSegments() { private long randomNumberOfSegments() {
...@@ -128,7 +142,7 @@ public class SystemSetup { ...@@ -128,7 +142,7 @@ public class SystemSetup {
} }
private Task generateTask() { private Task generateTask() {
boolean serial = randomTaskRatio() > this.ratio; boolean serial = randomTaskRatio(0) > this.ratio;
long period = randomTaskPeriod(serial); long period = randomTaskPeriod(serial);
long numberOfSegments = serial ? 1 : randomNumberOfSegments(); long numberOfSegments = serial ? 1 : randomNumberOfSegments();
long parallelNumberOfJobs = serial ? 1 : randomNumberOfJobs(); long parallelNumberOfJobs = serial ? 1 : randomNumberOfJobs();
...@@ -154,13 +168,13 @@ public class SystemSetup { ...@@ -154,13 +168,13 @@ public class SystemSetup {
} }
public SystemSetup build() { public SystemSetup build() {
this.ratio = randomTaskRatio(); this.ratio = randomTaskRatio(this.parallelTaskRatio);
Set<Task> taskSet = generateTaskSet(); Set<Task> taskSet = generateTaskSet();
return new SystemSetup(taskSet, numberOfProcessors); return new SystemSetup(taskSet, numberOfProcessors);
} }
public void rebuild(SystemSetup systemSetup) { public void rebuild(SystemSetup systemSetup) {
this.ratio = randomTaskRatio(); this.ratio = randomTaskRatio(this.parallelTaskRatio);
systemSetup.tasks = generateTaskSet(); systemSetup.tasks = generateTaskSet();
} }
......
...@@ -9,13 +9,15 @@ import mvd.jester.simulator.MaiaBertogna; ...@@ -9,13 +9,15 @@ import mvd.jester.simulator.MaiaBertogna;
import mvd.jester.simulator.SchmidMottok; import mvd.jester.simulator.SchmidMottok;
import mvd.jester.simulator.internals.TaskContextInterface; import mvd.jester.simulator.internals.TaskContextInterface;
import mvd.jester.tests.AbstractTest; import mvd.jester.tests.AbstractTest;
import mvd.jester.tests.ChwaLee;
/** /**
* EarliestDeadineFirst * EarliestDeadineFirst
*/ */
public class EarliestDeadlineFirst implements PriorityManager { public class EarliestDeadlineFirst implements PriorityManager {
final static Set<Class<? extends AbstractTest>> abstractTests = new HashSet<>(); final static Set<Class<? extends AbstractTest>> abstractTests =
new HashSet<>(Arrays.asList(ChwaLee.class));
final static Set<Class<? extends AbstractSimulator>> abstractSimulators = final static Set<Class<? extends AbstractSimulator>> abstractSimulators =
new HashSet<>(Arrays.asList(MaiaBertogna.class, SchmidMottok.class)); new HashSet<>(Arrays.asList(MaiaBertogna.class, SchmidMottok.class));
...@@ -29,8 +31,7 @@ public class EarliestDeadlineFirst implements PriorityManager { ...@@ -29,8 +31,7 @@ public class EarliestDeadlineFirst implements PriorityManager {
*/ */
@Override @Override
public int compare(Task t1, Task t2) { public int compare(Task t1, Task t2) {
throw new RuntimeException( return (int) (t1.getDeadline() - t2.getDeadline());
"Earliest Deadline First does not have Priority Manager for tasks");
} }
@Override @Override
...@@ -44,12 +45,23 @@ public class EarliestDeadlineFirst implements PriorityManager { ...@@ -44,12 +45,23 @@ public class EarliestDeadlineFirst implements PriorityManager {
} }
@Override @Override
public boolean hasTest(Class<? extends AbstractTest> abstractTestClass) {
return abstractTests.contains(abstractTestClass);
}
@Override
public boolean hasSimulator(AbstractSimulator abstractSimulator) { public boolean hasSimulator(AbstractSimulator abstractSimulator) {
return abstractSimulators.contains(abstractSimulator.getClass()); return abstractSimulators.contains(abstractSimulator.getClass());
} }
@Override @Override
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractSimulatorClass) {
return abstractSimulators.contains(abstractSimulatorClass);
}
@Override
public String getName() { public String getName() {
return "EDF"; return "EDF";
} }
} }
...@@ -16,8 +16,12 @@ public interface PriorityManager { ...@@ -16,8 +16,12 @@ public interface PriorityManager {
public boolean hasTest(AbstractTest abstractTest); public boolean hasTest(AbstractTest abstractTest);
public boolean hasTest(Class<? extends AbstractTest> abstractTestClass);
public boolean hasSimulator(AbstractSimulator abstractTest); public boolean hasSimulator(AbstractSimulator abstractTest);
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractTestClass);
public String getName(); public String getName();
} }
...@@ -40,13 +40,24 @@ public class RateMonotonic implements PriorityManager { ...@@ -40,13 +40,24 @@ public class RateMonotonic implements PriorityManager {
} }
@Override @Override
public boolean hasTest(Class<? extends AbstractTest> abstractTestClass) {
return abstractTests.contains(abstractTestClass);
}
@Override
public boolean hasSimulator(AbstractSimulator abstractSimulator) { public boolean hasSimulator(AbstractSimulator abstractSimulator) {
return abstractSimulators.contains(abstractSimulator.getClass()); return abstractSimulators.contains(abstractSimulator.getClass());
} }
@Override @Override
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractSimulatorClass) {
return abstractSimulators.contains(abstractSimulatorClass);
}
@Override
public String getName() { public String getName() {
return "RM"; return "RM";
} }
} }
...@@ -10,7 +10,7 @@ import mvd.jester.model.SystemSetup; ...@@ -10,7 +10,7 @@ import mvd.jester.model.SystemSetup;
import mvd.jester.model.Task; import mvd.jester.model.Task;
import mvd.jester.priority.PriorityManager; import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic; import mvd.jester.priority.RateMonotonic;
import mvd.jester.PairInterface; import mvd.jester.TypeInterface;
import mvd.jester.info.SchedulingInfo; import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo; import mvd.jester.info.TerminationInfo;
import mvd.jester.simulator.internals.ProcessorContext; import mvd.jester.simulator.internals.ProcessorContext;
...@@ -20,7 +20,7 @@ import mvd.jester.simulator.internals.TaskContextInterface; ...@@ -20,7 +20,7 @@ import mvd.jester.simulator.internals.TaskContextInterface;
/** /**
* AbstractSimulator * AbstractSimulator
*/ */
public abstract class AbstractSimulator implements SimulatorInterface, PairInterface { public abstract class AbstractSimulator implements SimulatorInterface, TypeInterface {
protected final SystemSetup systemSetup; protected final SystemSetup systemSetup;
protected final Set<ProcessorContext> processors; protected final Set<ProcessorContext> processors;
...@@ -43,7 +43,8 @@ public abstract class AbstractSimulator implements SimulatorInterface, PairInter ...@@ -43,7 +43,8 @@ public abstract class AbstractSimulator implements SimulatorInterface, PairInter
@Override @Override
public SchedulingInfo runSimulation(PriorityManager priorityManager) { public SchedulingInfo runSimulation(PriorityManager priorityManager) {
SchedulingInfo schedulingInfo = new SchedulingInfo(); SchedulingInfo schedulingInfo = new SchedulingInfo(systemSetup.getParallelTaskRatio(),
systemSetup.getUtilization());
init(priorityManager); init(priorityManager);
for (int t = 0; t < hyperPeriod; ++t) { for (int t = 0; t < hyperPeriod; ++t) {
if (!releaseTasks(t)) { if (!releaseTasks(t)) {
...@@ -70,7 +71,7 @@ public abstract class AbstractSimulator implements SimulatorInterface, PairInter ...@@ -70,7 +71,7 @@ public abstract class AbstractSimulator implements SimulatorInterface, PairInter
schedulingInfo.addTerminationInfo(terminationInfo); schedulingInfo.addTerminationInfo(terminationInfo);
if (t >= tc.getDeadline()) { if (t >= tc.getDeadline()) {
EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!"); EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!");
schedulingInfo.setFailedTemrinationInfo(terminationInfo); schedulingInfo.setFailedTerminationInfo(terminationInfo);
return schedulingInfo; return schedulingInfo;
} }
......
...@@ -3,7 +3,7 @@ package mvd.jester.tests; ...@@ -3,7 +3,7 @@ package mvd.jester.tests;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import mvd.jester.PairInterface; import mvd.jester.TypeInterface;
import mvd.jester.info.TerminationInfo; import mvd.jester.info.TerminationInfo;
import mvd.jester.model.SystemSetup; import mvd.jester.model.SystemSetup;
import mvd.jester.model.Task; import mvd.jester.model.Task;
...@@ -11,7 +11,7 @@ import mvd.jester.model.Task; ...@@ -11,7 +11,7 @@ import mvd.jester.model.Task;
/** /**
* AbstractTest * AbstractTest
*/ */
public abstract class AbstractTest implements TestInterface, PairInterface { public abstract class AbstractTest implements TestInterface, TypeInterface {
protected final Map<Task, TerminationInfo> responseTimes; protected final Map<Task, TerminationInfo> responseTimes;
protected final SystemSetup systemSetup; protected final SystemSetup systemSetup;
......
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<Segment> 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";
}
}
...@@ -30,7 +30,8 @@ public class MaiaBertogna extends AbstractTest { ...@@ -30,7 +30,8 @@ public class MaiaBertogna extends AbstractTest {
responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); 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 @Override
......
...@@ -30,7 +30,8 @@ public class SchmidMottok extends AbstractTest { ...@@ -30,7 +30,8 @@ public class SchmidMottok extends AbstractTest {
responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); 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 @Override
......
...@@ -24,8 +24,8 @@ public class Logger { ...@@ -24,8 +24,8 @@ public class Logger {
} }
public void log(String line) { public void log(Appendable sb) {
printWriter.println(line); printWriter.write(sb.toString());
} }
public void finalize() { public void finalize() {
......
package mvd.jester.priority; package mvd.jester.priority;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashSet; import java.util.HashSet;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
...@@ -23,7 +22,7 @@ public class TestEarliestDeadlineFirst { ...@@ -23,7 +22,7 @@ public class TestEarliestDeadlineFirst {
TaskContext tc1 = new TaskContext(t1, 0); TaskContext tc1 = new TaskContext(t1, 0);
TaskContext tc2 = new TaskContext(t2, 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); assertTrue(edf.compare(tc1, tc2) < 0);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment