diff --git a/.gitignore b/.gitignore index b57e62e..25f5b2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /.vscode /.settings +/results /target \ No newline at end of file diff --git a/src/main/java/mvd/jester/App.java b/src/main/java/mvd/jester/App.java index d70be57..7c51665 100644 --- a/src/main/java/mvd/jester/App.java +++ b/src/main/java/mvd/jester/App.java @@ -1,6 +1,8 @@ package mvd.jester; import mvd.jester.model.SystemSetup; +import mvd.jester.priority.EarliestDeadlineFirst; +import mvd.jester.priority.RateMonotonic; /** @@ -10,7 +12,10 @@ import mvd.jester.model.SystemSetup; 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, 4000); + + te.registerSchedulingAlgorithm(new RateMonotonic()); + te.registerSchedulingAlgorithm(new EarliestDeadlineFirst()); te.registerTestPair(mvd.jester.tests.MaiaBertogna.class, mvd.jester.simulator.MaiaBertogna.class); diff --git a/src/main/java/mvd/jester/TestEnvironment.java b/src/main/java/mvd/jester/TestEnvironment.java index a652023..ceac175 100644 --- a/src/main/java/mvd/jester/TestEnvironment.java +++ b/src/main/java/mvd/jester/TestEnvironment.java @@ -1,13 +1,14 @@ package mvd.jester; -import java.io.PrintWriter; 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.Table; 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; @@ -20,44 +21,88 @@ public class TestEnvironment { private final long numberOfTaskSets; private final SystemSetup systemSetup; private final SystemSetup.Builder builder; - private final Map, Constructor> abstractTestPairs; + private final Set> abstractTests; + private final Set> abstractSimulators; + private final Set schedulingAlgorithms; public TestEnvironment(SystemSetup.Builder builder, long numberOfTaskSets) { this.numberOfTaskSets = numberOfTaskSets; - abstractTestPairs = new HashMap<>(); + this.abstractTests = new HashSet<>(); + this.abstractSimulators = new HashSet<>(); + this.schedulingAlgorithms = new HashSet<>(); this.builder = builder; this.systemSetup = builder.build(); } + public TestEnvironment registerSchedulingAlgorithm(PriorityManager priorityManager) { + schedulingAlgorithms.add(priorityManager); + + return this; + } + + public TestEnvironment registerTest(Class abstractTest) { + try { + abstractTests.add(abstractTest.getConstructor(SystemSetup.class)); + } catch (Exception e) { + System.out.println("Missing constructor for abstract test!"); + } + + return this; + } + + public TestEnvironment registerSimulator(Class abstractSimulator) { + try { + abstractSimulators.add(abstractSimulator.getConstructor(SystemSetup.class)); + } catch (Exception e) { + System.out.println("Missing constructor for abstract simulator!"); + } + + return this; + } + public TestEnvironment registerTestPair(Class abstractTest, Class abstractSimulator) { try { - abstractTestPairs.put(abstractTest.getConstructor(SystemSetup.class), - abstractSimulator.getConstructor(SystemSetup.class)); + abstractTests.add(abstractTest.getConstructor(SystemSetup.class)); + } catch (Exception e) { + System.out.println("Missing constructor for abstract test!"); + } + try { + abstractSimulators.add(abstractSimulator.getConstructor(SystemSetup.class)); } catch (Exception e) { - System.out.println("Missing constructor!"); + System.out.println("Missing constructor for abstract simulator!"); } return this; } public void runTests() { - Map testPairs = new HashMap<>(); + Set abstractTestInstances = new HashSet<>(); + Set abstractSimulatorInstances = new HashSet<>(); Map> testResults = new HashMap<>(); Map> simulatorResults = new HashMap<>(); + // Map> testResults = new HashMap<>(); + // Map> simulatorResults = + // new HashMap<>(); - for (Map.Entry, Constructor> kv : abstractTestPairs - .entrySet()) { + for (Constructor c : abstractTests) { try { - testPairs.put(kv.getKey().newInstance(this.systemSetup), - kv.getValue().newInstance(this.systemSetup)); + abstractTestInstances.add(c.newInstance(this.systemSetup)); } catch (Exception e) { System.out.println("Could not instantiate object of AbstractTest!"); } } + for (Constructor c : abstractSimulators) { + try { + abstractSimulatorInstances.add(c.newInstance(this.systemSetup)); + } catch (Exception e) { + System.out.println("Could not instantiate object of AbstractSimulator!"); + } + } + long checkedTasksets = 0; while (checkedTasksets < numberOfTaskSets) { @@ -74,29 +119,28 @@ public class TestEnvironment { } long roundedUtilization = (long) (utilization * 10); - for (Map.Entry kv : testPairs.entrySet()) { - boolean schedCheck = kv.getKey().runSchedulabilityCheck(); - boolean simCheck = kv.getValue().runSimulation(); - if (schedCheck) { - testResults - .computeIfAbsent(roundedUtilization, - k -> new HashMap()) - .compute(kv.getKey(), (k, v) -> (v == null) ? 1 : v + 1); - } - if (simCheck) { - simulatorResults - .computeIfAbsent(roundedUtilization, - k -> new HashMap()) - .compute(kv.getValue(), (k, v) -> (v == null) ? 1 : v + 1); + + for (PriorityManager priorityManager : schedulingAlgorithms) { + for (AbstractTest test : abstractTestInstances) { + if (priorityManager.hasTest(test) + && test.runSchedulabilityCheck(priorityManager)) { + testResults + .computeIfAbsent(roundedUtilization, + k -> new HashMap()) + .compute(test, (k, v) -> (v == null) ? 1 : v + 1); + } } - if (schedCheck == true && simCheck == false) { - try (PrintWriter out = - new PrintWriter("results/manualCheck" + checkedTasksets + ".txt")) { - out.println(systemSetup); - } catch (Exception e) { - System.out.println("Ähm something went horribly wrong!"); + + for (AbstractSimulator simulator : abstractSimulatorInstances) { + if (priorityManager.hasSimulator(simulator) + && simulator.runSimulation(priorityManager)) { + simulatorResults + .computeIfAbsent(roundedUtilization, + k -> new HashMap()) + .compute(simulator, (k, v) -> (v == null) ? 1 : v + 1); } } + } builder.addTask(systemSetup); @@ -104,11 +148,11 @@ public class TestEnvironment { } } - logResults(testPairs.keySet(), testResults); - logSimulations(new HashSet(testPairs.values()), simulatorResults); + logTestResults(abstractTestInstances, testResults); + logSimulationResults(abstractSimulatorInstances, simulatorResults); } - private void logResults(Set testCases, + private void logTestResults(Set testCases, Map> results) { LocalTime date = LocalTime.now(); Logger log = new Logger("./results/results_" + systemSetup.getNumberOfProcessors() + "_" @@ -138,7 +182,7 @@ public class TestEnvironment { log.finalize(); } - private void logSimulations(Set testCases, + private void logSimulationResults(Set testCases, Map> results) { LocalTime date = LocalTime.now(); Logger log = new Logger("./results/results_sim_" + systemSetup.getNumberOfProcessors() + "_" diff --git a/src/main/java/mvd/jester/model/SystemSetup.java b/src/main/java/mvd/jester/model/SystemSetup.java index dc97c8e..9ab198c 100644 --- a/src/main/java/mvd/jester/model/SystemSetup.java +++ b/src/main/java/mvd/jester/model/SystemSetup.java @@ -4,22 +4,21 @@ import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import mvd.jester.priority.PriorityManager; -import mvd.jester.priority.RateMonotonic; /** * TaskSet */ public class SystemSetup { - private SortedTaskSet tasks; + private Set tasks; private final long numberOfProcessors; - public SystemSetup(SortedTaskSet tasks, long numberOfProcessors) { + public SystemSetup(Set tasks, long numberOfProcessors) { this.tasks = tasks; this.numberOfProcessors = numberOfProcessors; } @@ -27,11 +26,11 @@ public class SystemSetup { /** * @return the tasks */ - public SortedTaskSet getTasks() { + public Set getTasks() { return tasks; } - public void setTasks(SortedTaskSet tasks) { + public void setTasks(Set tasks) { this.tasks = tasks; } @@ -88,7 +87,6 @@ public class SystemSetup { private long maxNumberOfJobs = 3 * numberOfProcessors / 2; private long minWcet = 1; private long ratio = randomTaskRatio(); - private PriorityManager priorityManager = new RateMonotonic(); public Builder() { @@ -139,8 +137,9 @@ public class SystemSetup { return new Task(period, segments); } - private SortedTaskSet generateTaskSet() { - SortedTaskSet taskSet = new SortedTaskSet(priorityManager); + private Set generateTaskSet() { + // SortedTaskSet taskSet = new SortedTaskSet(priorityManager); + Set taskSet = new HashSet<>(); for (int i = 0; i < 4; ++i) { Task task = generateTask(); @@ -152,7 +151,7 @@ public class SystemSetup { public SystemSetup build() { this.ratio = randomTaskRatio(); - SortedTaskSet taskSet = generateTaskSet(); + Set taskSet = generateTaskSet(); return new SystemSetup(taskSet, numberOfProcessors); } @@ -185,11 +184,6 @@ public class SystemSetup { return this; } - public Builder setPriorityManager(PriorityManager priorityManager) { - this.priorityManager = priorityManager; - return this; - } - /** * @param maxNumberOfJobs the maxNumberOfJobs to set */ @@ -200,5 +194,4 @@ public class SystemSetup { } } - } diff --git a/src/main/java/mvd/jester/priority/EarliestDeadineFirst.java b/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java similarity index 69% rename from src/main/java/mvd/jester/priority/EarliestDeadineFirst.java rename to src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java index 4d4ea23..96d4f5f 100644 --- a/src/main/java/mvd/jester/priority/EarliestDeadineFirst.java +++ b/src/main/java/mvd/jester/priority/EarliestDeadlineFirst.java @@ -1,12 +1,22 @@ package mvd.jester.priority; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import mvd.jester.model.Task; +import mvd.jester.simulator.AbstractSimulator; +import mvd.jester.simulator.MaiaBertogna; import mvd.jester.simulator.internals.TaskContextInterface; +import mvd.jester.tests.AbstractTest; /** * EarliestDeadineFirst */ -public class EarliestDeadineFirst implements PriorityManager { +public class EarliestDeadlineFirst implements PriorityManager { + + final static Set> abstractTests = new HashSet<>(); + final static Set> abstractSimulators = + new HashSet<>(Arrays.asList(MaiaBertogna.class)); /** * Compare the priority of two tasks according to the Rate Monotonic policy @@ -26,4 +36,19 @@ public class EarliestDeadineFirst implements PriorityManager { public int compare(TaskContextInterface t1, TaskContextInterface t2) { return (int) (t1.getDeadline() - t2.getDeadline()); } + + @Override + public boolean hasTest(AbstractTest abstractTest) { + return abstractTests.contains(abstractTest.getClass()); + } + + @Override + public boolean hasSimulator(AbstractSimulator abstractSimulator) { + return abstractSimulators.contains(abstractSimulator.getClass()); + } + + @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 f87036d..5815d77 100644 --- a/src/main/java/mvd/jester/priority/PriorityManager.java +++ b/src/main/java/mvd/jester/priority/PriorityManager.java @@ -1,7 +1,9 @@ package mvd.jester.priority; import mvd.jester.model.Task; +import mvd.jester.simulator.AbstractSimulator; import mvd.jester.simulator.internals.TaskContextInterface; +import mvd.jester.tests.AbstractTest; /** * PriorityManager @@ -12,4 +14,10 @@ public interface PriorityManager { public int compare(TaskContextInterface t1, TaskContextInterface t2); + public boolean hasTest(AbstractTest abstractTest); + + public boolean hasSimulator(AbstractSimulator abstractTest); + + public String getName(); + } diff --git a/src/main/java/mvd/jester/priority/RateMonotonic.java b/src/main/java/mvd/jester/priority/RateMonotonic.java index 7b23fc1..4698e3e 100644 --- a/src/main/java/mvd/jester/priority/RateMonotonic.java +++ b/src/main/java/mvd/jester/priority/RateMonotonic.java @@ -1,10 +1,21 @@ package mvd.jester.priority; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import mvd.jester.model.Task; +import mvd.jester.simulator.AbstractSimulator; import mvd.jester.simulator.internals.TaskContextInterface; +import mvd.jester.tests.AbstractTest; public class RateMonotonic implements PriorityManager { + final static Set> abstractTests = new HashSet<>(Arrays + .asList(mvd.jester.tests.MaiaBertogna.class, mvd.jester.tests.SchmidMottok.class)); + final static Set> abstractSimulators = + new HashSet<>(Arrays.asList(mvd.jester.simulator.MaiaBertogna.class, + mvd.jester.simulator.SchmidMottok.class)); + /** * Compare the priority of two tasks according to the Rate Monotonic policy * @@ -22,4 +33,20 @@ public class RateMonotonic implements PriorityManager { public int compare(TaskContextInterface t1, TaskContextInterface t2) { return Long.compare(t1.getTask().getPeriod(), t2.getTask().getPeriod()); } + + @Override + public boolean hasTest(AbstractTest abstractTest) { + return abstractTests.contains(abstractTest.getClass()); + } + + @Override + public boolean hasSimulator(AbstractSimulator abstractSimulator) { + return abstractSimulators.contains(abstractSimulator.getClass()); + } + + @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 d64907e..0a8266d 100644 --- a/src/main/java/mvd/jester/simulator/AbstractSimulator.java +++ b/src/main/java/mvd/jester/simulator/AbstractSimulator.java @@ -6,6 +6,8 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; import mvd.jester.model.SystemSetup; +import mvd.jester.model.Task; +import mvd.jester.priority.PriorityManager; import mvd.jester.priority.RateMonotonic; import mvd.jester.simulator.internals.ProcessorContext; import mvd.jester.simulator.internals.SortedTaskContextSet; @@ -19,7 +21,7 @@ public abstract class AbstractSimulator implements SimulatorInterface { protected final SystemSetup systemSetup; protected final Set processors; - protected final SortedTaskContextSet readyTasks; + protected Set readyTasks; protected long hyperPeriod; AbstractSimulator(SystemSetup systemSetup) { @@ -29,15 +31,16 @@ public abstract class AbstractSimulator implements SimulatorInterface { for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) { processors.add(new ProcessorContext(i)); } - this.hyperPeriod = systemSetup.getTasks().last().getPeriod() * 2 /* * 10 */; + this.hyperPeriod = getHyperPeriod(); + } protected abstract boolean releaseTasks(long timeStep); @Override - public boolean runSimulation() { - init(); + public boolean runSimulation(PriorityManager priorityManager) { + init(priorityManager); for (int t = 0; t < hyperPeriod; ++t) { if (!releaseTasks(t)) { return false; @@ -70,12 +73,12 @@ public abstract class AbstractSimulator implements SimulatorInterface { return true; } - private void init() { - this.readyTasks.clear(); + private void init(PriorityManager priorityManager) { + this.readyTasks = new SortedTaskContextSet(priorityManager); for (ProcessorContext p : processors) { p.setJob(null); } - this.hyperPeriod = systemSetup.getTasks().last().getPeriod() * 2; + this.hyperPeriod = getHyperPeriod(); } private Set sortProcessors(Set processors) { @@ -86,6 +89,11 @@ public abstract class AbstractSimulator implements SimulatorInterface { return sortedProcessors; } + private long getHyperPeriod() { + return systemSetup.getTasks().stream().max(Comparator.comparing(Task::getPeriod)).get() + .getPeriod() * 2; /* * 10 */ + } + private class ProcessorComparator implements Comparator { @Override diff --git a/src/main/java/mvd/jester/simulator/SimulatorInterface.java b/src/main/java/mvd/jester/simulator/SimulatorInterface.java index 5f986fb..a4eae6e 100644 --- a/src/main/java/mvd/jester/simulator/SimulatorInterface.java +++ b/src/main/java/mvd/jester/simulator/SimulatorInterface.java @@ -1,11 +1,13 @@ package mvd.jester.simulator; +import mvd.jester.priority.PriorityManager; + /** * SimulatorInterface */ public interface SimulatorInterface { - public boolean runSimulation(); + public boolean runSimulation(PriorityManager priorityManager); public String getName(); diff --git a/src/main/java/mvd/jester/simulator/internals/SortedTaskContextSet.java b/src/main/java/mvd/jester/simulator/internals/SortedTaskContextSet.java index 8716e8f..a16cb02 100644 --- a/src/main/java/mvd/jester/simulator/internals/SortedTaskContextSet.java +++ b/src/main/java/mvd/jester/simulator/internals/SortedTaskContextSet.java @@ -11,7 +11,7 @@ public class SortedTaskContextSet extends TreeSet { private static final long serialVersionUID = 4808544133562675597L; public SortedTaskContextSet(PriorityManager priorityMananger) { - super((t1, t2) -> priorityMananger.compare(t1.getTask(), t2.getTask())); + super((t1, t2) -> priorityMananger.compare(t1, t2)); } } diff --git a/src/main/java/mvd/jester/tests/AbstractTest.java b/src/main/java/mvd/jester/tests/AbstractTest.java index 5c7d819..49ba9b2 100644 --- a/src/main/java/mvd/jester/tests/AbstractTest.java +++ b/src/main/java/mvd/jester/tests/AbstractTest.java @@ -2,6 +2,7 @@ package mvd.jester.tests; import java.util.HashMap; import java.util.Map; +import java.util.Set; import mvd.jester.model.SystemSetup; import mvd.jester.model.Task; @@ -12,9 +13,11 @@ public abstract class AbstractTest implements TestInterface { protected final Map responseTimes; protected final SystemSetup systemSetup; + protected Set tasks; public AbstractTest(SystemSetup systemSetup) { this.systemSetup = systemSetup; this.responseTimes = new HashMap(); + this.tasks = systemSetup.getTasks(); } } diff --git a/src/main/java/mvd/jester/tests/MaiaBertogna.java b/src/main/java/mvd/jester/tests/MaiaBertogna.java index dafc9c5..4a6eaa2 100644 --- a/src/main/java/mvd/jester/tests/MaiaBertogna.java +++ b/src/main/java/mvd/jester/tests/MaiaBertogna.java @@ -4,7 +4,9 @@ import java.math.RoundingMode; import java.util.Map.Entry; import com.google.common.math.LongMath; import mvd.jester.model.Segment; +import mvd.jester.model.SortedTaskSet; import mvd.jester.model.Task; +import mvd.jester.priority.PriorityManager; import mvd.jester.model.SystemSetup; /** @@ -17,9 +19,11 @@ public class MaiaBertogna extends AbstractTest { } @Override - public boolean runSchedulabilityCheck() { + public boolean runSchedulabilityCheck(PriorityManager priorityManager) { + tasks = new SortedTaskSet(priorityManager); + tasks.addAll(systemSetup.getTasks()); responseTimes.clear(); - for (Task t : systemSetup.getTasks()) { + for (Task t : tasks) { responseTimes.put(t, calculateResponseTime(t)); } @@ -46,7 +50,7 @@ public class MaiaBertogna extends AbstractTest { previousResponseTime = responseTime; long taskInterference = 0; - for (Task t : systemSetup.getTasks()) { + for (Task t : tasks) { if (t.getPeriod() < task.getPeriod()) { long maxNumberOfJobsOfT = t.getMaximumParallelism(); for (int p = 0; p < maxNumberOfJobsOfT; ++p) { diff --git a/src/main/java/mvd/jester/tests/SchmidMottok.java b/src/main/java/mvd/jester/tests/SchmidMottok.java index 3c89928..16d278f 100644 --- a/src/main/java/mvd/jester/tests/SchmidMottok.java +++ b/src/main/java/mvd/jester/tests/SchmidMottok.java @@ -4,7 +4,9 @@ import java.math.RoundingMode; import java.util.Map.Entry; import com.google.common.math.LongMath; import mvd.jester.model.Segment; +import mvd.jester.model.SortedTaskSet; import mvd.jester.model.Task; +import mvd.jester.priority.PriorityManager; import mvd.jester.model.SystemSetup; /** @@ -17,9 +19,11 @@ public class SchmidMottok extends AbstractTest { } @Override - public boolean runSchedulabilityCheck() { + public boolean runSchedulabilityCheck(PriorityManager priorityManager) { + tasks = new SortedTaskSet(priorityManager); + tasks.addAll(systemSetup.getTasks()); responseTimes.clear(); - for (Task t : systemSetup.getTasks()) { + for (Task t : tasks) { responseTimes.put(t, calculateResponseTime(t)); } @@ -47,7 +51,7 @@ public class SchmidMottok extends AbstractTest { previousResponseTime = responseTime; double taskInterference = 0; - for (Task t : systemSetup.getTasks()) { + for (Task t : tasks) { if (t.getPeriod() < task.getPeriod()) { long numberOfJobs = t.getMaximumParallelism() > numberOfProcessors ? numberOfProcessors diff --git a/src/main/java/mvd/jester/tests/TestInterface.java b/src/main/java/mvd/jester/tests/TestInterface.java index 8b2b4fa..b4d9a4e 100644 --- a/src/main/java/mvd/jester/tests/TestInterface.java +++ b/src/main/java/mvd/jester/tests/TestInterface.java @@ -1,11 +1,13 @@ package mvd.jester.tests; +import mvd.jester.priority.PriorityManager; + /** * TestInterface */ public interface TestInterface { - public boolean runSchedulabilityCheck(); + public boolean runSchedulabilityCheck(PriorityManager priorityManager); public String getName();