Commit 4f834394 by Michael Schmid

added refactoring for Stats library

parent 6b1ef83a
......@@ -12,17 +12,23 @@ import mvd.jester.priority.RateMonotonic;
public class App {
public static void main(String[] args) {
SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8);
TestEnvironment te = new TestEnvironment(builder, 40000);
TestEnvironment te = new TestEnvironment(builder, 30000);
te.registerSchedulingAlgorithm(new RateMonotonic());
te.registerSchedulingAlgorithm(new EarliestDeadlineFirst());
te.registerTestPair(mvd.jester.tests.MaiaBertogna.class,
mvd.jester.simulator.MaiaBertogna.class);
// te.registerTest(mvd.jester.tests.SchmidMottok.class);
// te.registerTest(mvd.jester.tests.MaiaBertogna.class);
te.registerSimulator(mvd.jester.simulator.MaiaBertogna.class);
te.registerSimulator(mvd.jester.simulator.SchmidMottok.class);
te.registerTestPair(mvd.jester.tests.SchmidMottok.class,
mvd.jester.simulator.SchmidMottok.class);
te.runTests();
// SystemSetup ss = builder.build();
// builder.addTask(ss);
// builder.addTask(ss);
// ss.writeToFile("Test3.txt");
}
}
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;
/**
* PairInterface
*/
public interface PairInterface {
public String getName();
}
package mvd.jester;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import com.google.common.collect.Table;
import com.google.common.math.Stats;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo;
import mvd.jester.simulator.AbstractSimulator;
import mvd.jester.tests.AbstractTest;
import mvd.jester.utils.Logger;
/**
* ResultCollector
*/
public class ResultCollector {
private final Table<Long, Pair<AbstractTest>, Set<SchedulingInfo>> testResults;
private final Table<Long, Pair<AbstractSimulator>, Set<SchedulingInfo>> simulatorResults;
private final Map<Long, Long> totalNumberOfTasksets;
private final long numberOfProcessors;
public ResultCollector(Table<Long, Pair<AbstractTest>, Set<SchedulingInfo>> testResults,
Table<Long, Pair<AbstractSimulator>, Set<SchedulingInfo>> simulatorResults,
Map<Long, Long> totalNumberOfTasksets, long numberOfProcessors) {
this.testResults = testResults;
this.simulatorResults = simulatorResults;
this.totalNumberOfTasksets = totalNumberOfTasksets;
this.numberOfProcessors = numberOfProcessors;
}
public void logAll() {
if (!testResults.isEmpty()) {
logResults(testResults, "test");
logMeanTardiness(simulatorResults, "test");
logFailedTardiness(testResults, "test");
}
if (!simulatorResults.isEmpty()) {
logResults(simulatorResults, "sim");
logMeanTardiness(simulatorResults, "sim");
logFailedTardiness(simulatorResults, "sim");
}
}
public <T extends PairInterface> void logResults(
Table<Long, Pair<T>, Set<SchedulingInfo>> results, String type) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/results_" + type + "_" + numberOfProcessors + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
String firstLine = new String("Utilization\tTotal");
if (!results.isEmpty()) {
for (Pair<T> pair : results.columnKeySet()) {
firstLine = firstLine + "\t" + pair.getName();
}
log.log(firstLine);
for (Long util : totalNumberOfTasksets.keySet()) {
String line =
String.valueOf((double) util / 10) + "\t" + totalNumberOfTasksets.get(util);
for (Pair<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(
Table<Long, Pair<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\tTotal");
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) + "\t" + totalNumberOfTasksets.get(kv);
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 logMeanTardiness(
Table<Long, Pair<T>, Set<SchedulingInfo>> results, String type) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/mean_tardiness_" + type + "_" + numberOfProcessors + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
String firstLine = new String("Utilization\tTotal");
if (!results.isEmpty()) {
for (Pair<T> pair : results.columnKeySet()) {
firstLine = firstLine + "\t" + pair.getName();
}
log.log(firstLine);
for (Long kv : totalNumberOfTasksets.keySet()) {
String line =
String.valueOf((double) kv / 10) + "\t" + totalNumberOfTasksets.get(kv);
for (Pair<T> pair : results.columnKeySet()) {
Set<SchedulingInfo> simulationInfos = results.get(kv, pair);
List<Long> values = new ArrayList<>();
for (SchedulingInfo s : simulationInfos) {
for (TerminationInfo t : s.getTerminationInfos()) {
values.add(t.getLateness());
}
}
double meanTardiness = 0;
if (!values.isEmpty()) {
meanTardiness = Stats.meanOf(values.iterator());
}
line += "\t" + meanTardiness;
}
log.log(line);
}
}
log.finalize();
}
}
package mvd.jester;
import java.lang.reflect.Constructor;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.model.SystemSetup;
import mvd.jester.priority.PriorityManager;
import mvd.jester.simulator.AbstractSimulator;
import mvd.jester.tests.AbstractTest;
import mvd.jester.utils.Logger;
/**
* TestEnvironment
......@@ -79,18 +78,20 @@ public class TestEnvironment {
}
public void runTests() {
Set<TestPair> abstractTestInstances = new HashSet<>();
Set<SimulatorPair> abstractSimulatorInstances = new HashSet<>();
Set<Pair<AbstractTest>> abstractTestInstances = new HashSet<>();
Set<Pair<AbstractSimulator>> abstractSimulatorInstances = new HashSet<>();
Map<Long, Long> totalNumberOfTasks = new HashMap<>();
Map<Long, Long> totalNumberOfTasksets = new HashMap<>();
Table<Long, TestPair, Long> testResults = HashBasedTable.create();
Table<Long, SimulatorPair, Long> simulatorResults = HashBasedTable.create();
Table<Long, Pair<AbstractTest>, Set<SchedulingInfo>> testResults = HashBasedTable.create();
Table<Long, Pair<AbstractSimulator>, Set<SchedulingInfo>> simulatorResults =
HashBasedTable.create();
for (PriorityManager pm : schedulingAlgorithms) {
for (Constructor<? extends AbstractTest> c : abstractTests) {
try {
abstractTestInstances.add(new TestPair(pm, c.newInstance(this.systemSetup)));
abstractTestInstances
.add(new Pair<AbstractTest>(pm, c.newInstance(this.systemSetup)));
} catch (Exception e) {
System.out.println("Could not instantiate object of AbstractTest!");
}
......@@ -99,7 +100,7 @@ public class TestEnvironment {
for (Constructor<? extends AbstractSimulator> c : abstractSimulators) {
try {
abstractSimulatorInstances
.add(new SimulatorPair(pm, c.newInstance(this.systemSetup)));
.add(new Pair<AbstractSimulator>(pm, c.newInstance(this.systemSetup)));
} catch (Exception e) {
System.out.println("Could not instantiate object of AbstractSimulator!");
}
......@@ -123,33 +124,35 @@ public class TestEnvironment {
long roundedUtilization = (long) (utilization * 10);
totalNumberOfTasks.compute(roundedUtilization, (k, v) -> v == null ? 1 : v + 1);
totalNumberOfTasksets.compute(roundedUtilization, (k, v) -> v == null ? 1 : v + 1);
for (TestPair testInstance : abstractTestInstances) {
for (Pair<AbstractTest> testInstance : abstractTestInstances) {
PriorityManager priorityManager = testInstance.getPriorityManager();
AbstractTest abstractTest = testInstance.getAbstractTest();
AbstractTest abstractTest = testInstance.getAbstractValue();
if (!testResults.contains(roundedUtilization, testInstance)) {
testResults.put(roundedUtilization, testInstance, (long) 0);
testResults.put(roundedUtilization, testInstance, new HashSet<>());
}
if (priorityManager.hasTest(abstractTest)
&& abstractTest.runSchedulabilityCheck(priorityManager)) {
Long val = testResults.get(roundedUtilization, testInstance);
testResults.put(roundedUtilization, testInstance, val + 1);
if (priorityManager.hasTest(abstractTest)) {
SchedulingInfo schedulingInfo =
abstractTest.runSchedulabilityCheck(priorityManager);
testResults.get(roundedUtilization, testInstance).add(schedulingInfo);
}
}
for (SimulatorPair simulatorInstance : abstractSimulatorInstances) {
for (Pair<AbstractSimulator> simulatorInstance : abstractSimulatorInstances) {
PriorityManager priorityManager = simulatorInstance.getPriorityManager();
AbstractSimulator abstractSimulator = simulatorInstance.getAbstractSimulator();
AbstractSimulator abstractSimulator = simulatorInstance.getAbstractValue();
if (!simulatorResults.contains(roundedUtilization, simulatorInstance)) {
simulatorResults.put(roundedUtilization, simulatorInstance, (long) 0);
simulatorResults.put(roundedUtilization, simulatorInstance,
new HashSet<>());
}
if (priorityManager.hasSimulator(abstractSimulator)
&& abstractSimulator.runSimulation(priorityManager)) {
Long val = simulatorResults.get(roundedUtilization, simulatorInstance);
simulatorResults.put(roundedUtilization, simulatorInstance, val + 1);
if (priorityManager.hasSimulator(abstractSimulator)) {
SchedulingInfo schedulingInfo =
abstractSimulator.runSimulation(priorityManager);
simulatorResults.get(roundedUtilization, simulatorInstance)
.add(schedulingInfo);
}
}
......@@ -159,121 +162,12 @@ public class TestEnvironment {
}
}
logTestResults(testResults, totalNumberOfTasks);
logSimulationResults(simulatorResults, totalNumberOfTasks);
}
private void logTestResults(Table<Long, TestPair, Long> results,
Map<Long, Long> totalNumberOfTasks) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/results_" + systemSetup.getNumberOfProcessors() + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
String firstLine = new String("Utilization");
if (!results.isEmpty()) {
for (TestPair testPair : results.columnKeySet()) {
firstLine = firstLine + "\t" + testPair.getName();
}
log.log(firstLine);
ResultCollector resultCollector = new ResultCollector(testResults, simulatorResults,
totalNumberOfTasksets, systemSetup.getNumberOfProcessors());
for (Long util : totalNumberOfTasks.keySet()) {
String line =
String.valueOf((double) util / 10) + "\t" + totalNumberOfTasks.get(util);
for (TestPair simulatorPair : results.columnKeySet()) {
line += "\t" + results.get(util, simulatorPair);
}
log.log(line);
}
}
log.finalize();
resultCollector.logAll();
}
private void logSimulationResults(Table<Long, SimulatorPair, Long> results,
Map<Long, Long> totalNumberOfTasks) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/results_sim_" + systemSetup.getNumberOfProcessors() + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
String firstLine = new String("Utilization\tTotal");
if (!results.isEmpty()) {
for (SimulatorPair simulatorPair : results.columnKeySet()) {
firstLine = firstLine + "\t" + simulatorPair.getName();
}
log.log(firstLine);
for (Long kv : totalNumberOfTasks.keySet()) {
String line = String.valueOf((double) kv / 10) + "\t" + totalNumberOfTasks.get(kv);
for (SimulatorPair simulatorPair : results.columnKeySet()) {
line += "\t" + results.get(kv, simulatorPair);
}
log.log(line);
}
}
log.finalize();
}
private class SimulatorPair {
private final PriorityManager priorityManager;
private final AbstractSimulator abstractSimulator;
public SimulatorPair(PriorityManager priorityManager, AbstractSimulator abstractSimulator) {
this.abstractSimulator = abstractSimulator;
this.priorityManager = priorityManager;
}
/**
* @return the priorityManager
*/
public PriorityManager getPriorityManager() {
return priorityManager;
}
/**
* @return the abstractSimulator
*/
public AbstractSimulator getAbstractSimulator() {
return abstractSimulator;
}
public String getName() {
return abstractSimulator.getName() + "_" + priorityManager.getName();
}
}
private class TestPair {
private final PriorityManager priorityManager;
private final AbstractTest abstractTest;
public TestPair(PriorityManager priorityManager, AbstractTest abstractTest) {
this.abstractTest = abstractTest;
this.priorityManager = priorityManager;
}
/**
* @return the priorityManager
*/
public PriorityManager getPriorityManager() {
return priorityManager;
}
/**
* @return the abstractTest
*/
public AbstractTest getAbstractTest() {
return abstractTest;
}
public String getName() {
return abstractTest.getName() + "_" + priorityManager.getName();
}
}
}
package mvd.jester.info;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
/**
* DeadlineMissInfo
*/
public class SchedulingInfo {
private final Set<TerminationInfo> terminationInfos;
private Optional<TerminationInfo> failedTerminationInfo;
public SchedulingInfo() {
this.terminationInfos = new HashSet<>();
this.failedTerminationInfo = Optional.empty();
}
public SchedulingInfo(Set<TerminationInfo> terminationInfos) {
this.terminationInfos = terminationInfos;
}
public boolean checkTasksetFeasible() {
// return terminationInfos.isEmpty();
return !terminationInfos.stream().anyMatch(t -> t.getLateness() > 0);
}
public void addTerminationInfo(TerminationInfo terminationInfo) {
terminationInfos.add(terminationInfo);
}
/**
* @return the terminationInfos
*/
public Set<TerminationInfo> getTerminationInfos() {
return terminationInfos;
}
/**
* @return the failedTerminationInfo
*/
public Optional<TerminationInfo> getFailedTerminationInfo() {
return failedTerminationInfo;
}
public void setFailedTemrinationInfo(TerminationInfo failedTerminationInfo) {
this.failedTerminationInfo = Optional.of(failedTerminationInfo);
}
}
package mvd.jester.info;
/**
* TerminationInfo
*/
public class TerminationInfo {
private final long releaseTime;
private final long deadline;
private final long responseTime;
private final long lateness;
public TerminationInfo(long releaseTime, long deadline, long responseTime) {
this.releaseTime = releaseTime;
this.deadline = deadline;
this.responseTime = responseTime;
this.lateness = responseTime - deadline;
}
/**
* @return the deadline
*/
public long getDeadline() {
return deadline;
}
/**
* @return the lateness
*/
public long getLateness() {
return lateness;
}
/**
* @return the releaseTime
*/
public long getReleaseTime() {
return releaseTime;
}
/**
* @return the responseTime
*/
public long getResponseTime() {
return responseTime;
}
}
package mvd.jester.model;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
......@@ -56,7 +57,15 @@ public class SystemSetup {
return gson.toJson(tasks);
}
public static SystemSetup fromFile(String path) {
public void writeToFile(String path) {
try (PrintWriter pw = new PrintWriter(path)) {
pw.write(toString());
} catch (Exception e) {
System.err.println("Something went wrong when writing to file!");
}
}
public static SystemSetup readFromFile(String path) {
String jsonString;
try {
byte[] encoded = Files.readAllBytes(Paths.get(path));
......
......@@ -5,28 +5,31 @@ import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import com.google.common.collect.TreeMultiset;
import mvd.jester.model.SystemSetup;
import mvd.jester.model.Task;
import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic;
import mvd.jester.PairInterface;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo;
import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.SortedTaskContextSet;
import mvd.jester.simulator.internals.TaskContextInterface;
/**
* AbstractSimulator
*/
public abstract class AbstractSimulator implements SimulatorInterface {
public abstract class AbstractSimulator implements SimulatorInterface, PairInterface {
protected final SystemSetup systemSetup;
protected final Set<ProcessorContext> processors;
protected Set<TaskContextInterface> readyTasks;
protected TreeMultiset<TaskContextInterface> readyTasks;
protected long hyperPeriod;
AbstractSimulator(SystemSetup systemSetup) {
this.systemSetup = systemSetup;
this.readyTasks = new SortedTaskContextSet(new RateMonotonic());
this.readyTasks = TreeMultiset.create((t1, t2) -> new RateMonotonic().compare(t1, t2));
processors = new HashSet<>();
for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) {
processors.add(new ProcessorContext(i));
......@@ -39,11 +42,12 @@ public abstract class AbstractSimulator implements SimulatorInterface {
protected abstract boolean releaseTasks(long timeStep);
@Override
public boolean runSimulation(PriorityManager priorityManager) {
public SchedulingInfo runSimulation(PriorityManager priorityManager) {
SchedulingInfo schedulingInfo = new SchedulingInfo();
init(priorityManager);
for (int t = 0; t < hyperPeriod; ++t) {
if (!releaseTasks(t)) {
return false;
throw new RuntimeException("Could not release a task. This should not happen!");
}
Set<ProcessorContext> sortedProcessors = sortProcessors(processors);
......@@ -61,20 +65,25 @@ public abstract class AbstractSimulator implements SimulatorInterface {
Optional<TaskContextInterface> optionalTc = p.updateExecution(t);
if (optionalTc.isPresent()) {
TaskContextInterface tc = optionalTc.get();
TerminationInfo terminationInfo =
new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t);
schedulingInfo.addTerminationInfo(terminationInfo);
if (t >= tc.getDeadline()) {
EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!");
return false;
schedulingInfo.setFailedTemrinationInfo(terminationInfo);
return schedulingInfo;
}
readyTasks.remove(optionalTc.get());
}
}
}
return true;
return schedulingInfo;
}
private void init(PriorityManager priorityManager) {
this.readyTasks = new SortedTaskContextSet(priorityManager);
this.readyTasks = TreeMultiset.create((t1, t2) -> priorityManager.compare(t1, t2));
for (ProcessorContext p : processors) {
p.setJob(null);
}
......@@ -115,5 +124,4 @@ public abstract class AbstractSimulator implements SimulatorInterface {
}
}
}
package mvd.jester.simulator;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.priority.PriorityManager;
/**
......@@ -7,7 +8,7 @@ import mvd.jester.priority.PriorityManager;
*/
public interface SimulatorInterface {
public boolean runSimulation(PriorityManager priorityManager);
public SchedulingInfo runSimulation(PriorityManager priorityManager);
public String getName();
......
......@@ -15,4 +15,6 @@ public interface TaskContextInterface {
public Optional<JobContextInterface> getNextJob();
public long getDeadline();
public long getReleaseTime();
}
......@@ -16,16 +16,18 @@ public class TaskContext implements TaskContextInterface {
private final Task task;
private final ArrayList<SegmentContext> segments;
private final long deadline;
private final long releaseTime;
private int currentSegment;
private int segmentCounter;
public TaskContext(Task task, long timeStep) {
public TaskContext(Task task, long releaseTime) {
this.task = task;
this.segments = new ArrayList<>();
this.currentSegment = 0;
this.segmentCounter = 0;