Commit 11c72917 by Michael Schmid

Added simulator but there is still an error

parent 9e4cddba
package mvd.jester; package mvd.jester;
import java.io.File;
import mvd.jester.model.SystemSetup; import mvd.jester.model.SystemSetup;
import mvd.jester.tests.MaiaBertogna;
import mvd.jester.tests.SchmidMottok;
import mvd.jester.tests.TestEnvironment;
/** /**
* Hello world! * Hello world!
...@@ -11,14 +9,39 @@ import mvd.jester.tests.TestEnvironment; ...@@ -11,14 +9,39 @@ import mvd.jester.tests.TestEnvironment;
*/ */
public class App { public class App {
public static void main(String[] args) { public static void main(String[] args) {
boolean runTests = false;
if (runTests) {
SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8); SystemSetup.Builder builder = new SystemSetup.Builder().setNumberOfProcessors(8);
TestEnvironment te = new TestEnvironment(builder, 40000); TestEnvironment te = new TestEnvironment(builder, 40000);
te.registerTestInterface(SchmidMottok.class); // te.registerTestInterface(SchmidMottok.class);
te.registerTestInterface(MaiaBertogna.class); te.registerTestPair(mvd.jester.tests.MaiaBertogna.class,
mvd.jester.simulator.MaiaBertogna.class);
te.runTests(); te.runTests();
} else {
File folder = new File("results");
for (File f : folder.listFiles()) {
SystemSetup systemSetup = SystemSetup.fromFile(f.toPath().toString());
mvd.jester.simulator.MaiaBertogna mb_sim =
new mvd.jester.simulator.MaiaBertogna(systemSetup);
mvd.jester.tests.MaiaBertogna mb_test =
new mvd.jester.tests.MaiaBertogna(systemSetup);
boolean simCheck = mb_sim.runSimulation();
boolean schedCheck = mb_test.runSchedulabilityCheck();
if (simCheck == false && schedCheck == true) {
System.out.println(f.getName());
}
}
}
} }
} }
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 mvd.jester.model.SystemSetup;
import mvd.jester.simulator.AbstractSimulator;
import mvd.jester.tests.AbstractTest;
import mvd.jester.utils.Logger;
/**
* TestEnvironment
*/
public class TestEnvironment {
private final long numberOfTaskSets;
private final SystemSetup systemSetup;
private final SystemSetup.Builder builder;
private final Map<Constructor<? extends AbstractTest>, Constructor<? extends AbstractSimulator>> abstractTestPairs;
public TestEnvironment(SystemSetup.Builder builder, long numberOfTaskSets) {
this.numberOfTaskSets = numberOfTaskSets;
abstractTestPairs = new HashMap<>();
this.builder = builder;
this.systemSetup = builder.build();
}
public TestEnvironment registerTestPair(Class<? extends AbstractTest> abstractTest,
Class<? extends AbstractSimulator> abstractSimulator) {
try {
abstractTestPairs.put(abstractTest.getConstructor(SystemSetup.class),
abstractSimulator.getConstructor(SystemSetup.class));
} catch (Exception e) {
System.out.println("Missing constructor!");
}
return this;
}
public void runTests() {
Map<AbstractTest, AbstractSimulator> testPairs = new HashMap<>();
Map<Long, Map<AbstractTest, Long>> testResults = new HashMap<>();
Map<Long, Map<AbstractSimulator, Long>> simulatorResults = new HashMap<>();
for (Map.Entry<Constructor<? extends AbstractTest>, Constructor<? extends AbstractSimulator>> kv : abstractTestPairs
.entrySet()) {
try {
testPairs.put(kv.getKey().newInstance(this.systemSetup),
kv.getValue().newInstance(this.systemSetup));
} catch (Exception e) {
System.out.println("Could not instantiate object of AbstractTest!");
}
}
long checkedTasksets = 0;
while (checkedTasksets < numberOfTaskSets) {
builder.rebuild(this.systemSetup);
double utilization = this.systemSetup.getUtilization();
while (utilization <= this.systemSetup.getNumberOfProcessors()
&& checkedTasksets < numberOfTaskSets) {
checkedTasksets++;
if (checkedTasksets % 100 == 0) {
System.out.println(checkedTasksets + " bereits geschafft");
}
long roundedUtilization = (long) (utilization * 10);
for (Map.Entry<AbstractTest, AbstractSimulator> kv : testPairs.entrySet()) {
boolean schedCheck = kv.getKey().runSchedulabilityCheck();
boolean simCheck = kv.getValue().runSimulation();
if (schedCheck) {
testResults
.computeIfAbsent(roundedUtilization,
k -> new HashMap<AbstractTest, Long>())
.compute(kv.getKey(), (k, v) -> (v == null) ? 1 : v + 1);
}
if (simCheck) {
simulatorResults
.computeIfAbsent(roundedUtilization,
k -> new HashMap<AbstractSimulator, Long>())
.compute(kv.getValue(), (k, v) -> (v == null) ? 1 : v + 1);
}
if (schedCheck == true && simCheck == false) {
boolean sched = kv.getKey().runSchedulabilityCheck();
boolean sim = kv.getValue().runSimulation();
if (sched == true && sim == false) {
try (PrintWriter out = new PrintWriter(
"results/manualCheck" + checkedTasksets + ".txt")) {
out.println(systemSetup);
} catch (Exception e) {
System.out.println("Ähm something went horribly wrong!");
}
}
}
}
builder.addTask(systemSetup);
utilization = this.systemSetup.getUtilization();
}
}
logResults(testPairs.keySet(), testResults);
logSimulations(new HashSet<AbstractSimulator>(testPairs.values()), simulatorResults);
}
private void logResults(Set<AbstractTest> testCases,
Map<Long, Map<AbstractTest, Long>> results) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/results_" + systemSetup.getNumberOfProcessors() + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
String firstLine = new String("Utilization");
for (AbstractTest t : testCases) {
firstLine = firstLine + "\t" + t.getName();
}
log.log(firstLine);
for (Long util : results.keySet()) {
String line = String.valueOf((double) util / 10);
Map<AbstractTest, Long> tests = results.get(util);
for (AbstractTest t : testCases) {
if (tests.containsKey(t)) {
line += "\t" + tests.get(t);
} else {
line += "\t" + "0";
}
}
log.log(line);
}
log.finalize();
}
private void logSimulations(Set<AbstractSimulator> testCases,
Map<Long, Map<AbstractSimulator, Long>> results) {
LocalTime date = LocalTime.now();
Logger log = new Logger("./results/results_sim_" + systemSetup.getNumberOfProcessors() + "_"
+ date.getHour() + ":" + date.getMinute() + ".txt");
String firstLine = new String("Utilization");
for (AbstractSimulator t : testCases) {
firstLine = firstLine + "\t" + t.getName();
}
log.log(firstLine);
for (Long util : results.keySet()) {
String line = String.valueOf((double) util / 10);
Map<AbstractSimulator, Long> tests = results.get(util);
for (AbstractSimulator t : testCases) {
if (tests.containsKey(t)) {
line += "\t" + tests.get(t);
} else {
line += "\t" + "0";
}
}
log.log(line);
}
log.finalize();
}
}
package mvd.jester.model; package mvd.jester.model;
import com.google.common.math.LongMath; // import com.google.common.math.LongMath;
public class Segment { public class Segment {
......
package mvd.jester.model; package mvd.jester.model;
import java.lang.reflect.Type;
import java.util.TreeSet; import java.util.TreeSet;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import mvd.jester.priority.PriorityManager; import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic;
/** /**
* SortedTaskSet * SortedTaskSet
...@@ -13,4 +20,20 @@ public class SortedTaskSet extends TreeSet<Task> { ...@@ -13,4 +20,20 @@ public class SortedTaskSet extends TreeSet<Task> {
public SortedTaskSet(PriorityManager priorityMananger) { public SortedTaskSet(PriorityManager priorityMananger) {
super((t1, t2) -> priorityMananger.compare(t1, t2)); super((t1, t2) -> priorityMananger.compare(t1, t2));
} }
public static class Deserializer implements JsonDeserializer<SortedTaskSet> {
@Override
public SortedTaskSet deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
SortedTaskSet taskSet = new SortedTaskSet(new RateMonotonic());
if (json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
array.forEach(e -> {
taskSet.add(context.deserialize(e, Task.class));
});
}
return taskSet;
}
}
} }
package mvd.jester.model; package mvd.jester.model;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import mvd.jester.priority.PriorityManager; import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic; import mvd.jester.priority.RateMonotonic;
...@@ -45,6 +51,33 @@ public class SystemSetup { ...@@ -45,6 +51,33 @@ public class SystemSetup {
return utilization; return utilization;
} }
@Override
public String toString() {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
return gson.toJson(tasks);
}
public static SystemSetup fromFile(String path) {
String jsonString;
try {
byte[] encoded = Files.readAllBytes(Paths.get(path));
jsonString = new String(encoded, Charset.defaultCharset());
} catch (IOException e) {
System.out.println(e.getMessage());
jsonString = new String("");
}
return SystemSetup.fromString(jsonString);
}
public static SystemSetup fromString(String json) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(SortedTaskSet.class, new SortedTaskSet.Deserializer())
.create();
SortedTaskSet tasks = gson.fromJson(json, SortedTaskSet.class);
return new SystemSetup(tasks, 8);
}
public static class Builder { public static class Builder {
private long numberOfProcessors = 4; private long numberOfProcessors = 4;
private long minPeriod = 100; private long minPeriod = 100;
......
package mvd.jester.simulator;
import java.util.HashSet;
import java.util.Set;
import com.google.common.math.LongMath;
import mvd.jester.model.SystemSetup;
import mvd.jester.model.Task;
import mvd.jester.priority.RateMonotonic;
import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.SortedTaskContextSet;
import mvd.jester.simulator.internals.TaskContext;
/**
* AbstractSimulator
*/
public abstract class AbstractSimulator implements SimulatorInterface {
protected final SystemSetup systemSetup;
protected final Set<ProcessorContext> processors;
protected final SortedTaskContextSet readyTasks;
protected final long hyperPeriod;
AbstractSimulator(SystemSetup systemSetup) {
this.systemSetup = systemSetup;
this.readyTasks = new SortedTaskContextSet(new RateMonotonic());
processors = new HashSet<>();
for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) {
processors.add(new ProcessorContext(i));
}
this.hyperPeriod = systemSetup.getTasks().last().getPeriod() * 10;
// LongMath.pow(systemSetup.getTasks().last().getPeriod(), 2);
}
protected boolean releaseTasks(long timeStep) {
for (Task t : systemSetup.getTasks()) {
if (timeStep % t.getPeriod() == 0) {
if (!readyTasks.add(new TaskContext(t, timeStep))) {
return false;
}
}
}
return true;
}
}
package mvd.jester.simulator;
import java.util.Comparator;
import java.util.Optional;
import java.util.TreeSet;
import mvd.jester.model.SystemSetup;
import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.TaskContext;
/**
* MaiaBertogna
*/
public class MaiaBertogna extends AbstractSimulator {
public MaiaBertogna(SystemSetup systemSetup) {
super(systemSetup);
}
@Override
public boolean runSimulation() {
readyTasks.clear();
for (int t = 0; t < hyperPeriod; ++t) {
if (!releaseTasks(t)) {
return false;
}
TreeSet<ProcessorContext> sortedProcessors =
new TreeSet<>((p1, p2) -> (int) (!p1.getJob().isPresent() ? -1
: !p2.getJob().isPresent() ? 1 : -1));
processors.forEach(p -> sortedProcessors.add(p));
for (ProcessorContext p : sortedProcessors) {
for (TaskContext tc : readyTasks) {
if (p.acceptTask(tc, t)) {
break;
}
}
}
for (ProcessorContext p : processors) {
Optional<TaskContext> optionalTc = p.updateExecution(t);
if (optionalTc.isPresent()) {
TaskContext tc = optionalTc.get();
if (t >= tc.getDeadline()) {
return false;
}
readyTasks.remove(optionalTc.get());
}
}
}
return true;
}
@Override
public String getName() {
return "MaiaBertogna";
}
}
package mvd.jester.simulator;
import mvd.jester.model.SystemSetup;
/**
* SchmidMottok
*/
public class SchmidMottok extends AbstractSimulator {
SchmidMottok(SystemSetup systemSetup) {
super(systemSetup);
}
@Override
public boolean runSimulation() {
return false;
}
@Override
public String getName() {
return "SchmidMottok";
}
}
package mvd.jester.simulator;
/**
* SimulatorInterface
*/
public interface SimulatorInterface {
public boolean runSimulation();
public String getName();
}
package mvd.jester.simulator.internals;
import java.util.Optional;
/**
* Job
*
* @param <Job>
*/
public class JobContext {
private final TaskContext taskContext;
private final SegmentContext segmentContext;
private final long wcet;
private Optional<ProcessorContext> currentProcessor;
private long executionTime;
public JobContext(TaskContext taskContext, SegmentContext segmentContext) {
this.currentProcessor = Optional.empty();
this.taskContext = taskContext;
this.segmentContext = segmentContext;
this.wcet = segmentContext.getSegment().getJobWcet();
this.executionTime = wcet;
}
public Optional<TaskContext> updateExecution(long time) {
executionTime--;
if (executionTime == 0) {
// System.out.println("Time " + time + ": " + currentProcessor.get()
// + " finished execution of job " + this + "!");
currentProcessor.get().setJob(null);
currentProcessor = Optional.empty();
return taskContext.acceptNotification(time);
}
return Optional.empty();
}
public boolean checkExecutionTime() {
return executionTime > 0;
}
/**
* @return the wcet
*/
public long getWcet() {
return wcet;
}
/**
* @param processor the currentProcessor to set
*/
public void setCurrentProcessor(ProcessorContext processor) {
this.currentProcessor = Optional.ofNullable(processor);
}
/**
* @return the currentProcessor
*/
public Optional<ProcessorContext> getCurrentProcessor() {
return currentProcessor;
}
/**
* @return the segmentContext
*/
public SegmentContext getSegmentContext() {
return segmentContext;
}
/**
* @return the taskContext
*/
public TaskContext getTaskContext() {
return taskContext;
}
@Override
public String toString() {
return "(jobWcet=" + wcet + ")";
}
}
package mvd.jester.simulator.internals;
import java.util.Optional;
/**
* Processor
*/
public class ProcessorContext {
private Optional<JobContext> currentJob;
private final long processorId;
public ProcessorContext(long processorId) {
currentJob = Optional.empty();
this.processorId = processorId;
}
public void setJob(JobContext job) {
this.currentJob = Optional.ofNullable(job);
}
/**
* @return the currentJob
*/
public Optional<JobContext> getJob() {
return currentJob;
}
public Optional<TaskContext> updateExecution(long time) {
if (currentJob.isPresent()) {
return currentJob.get().updateExecution(time);
}
return Optional.empty();
}
public boolean acceptTask(TaskContext taskContext, int t) {
if (!currentJob.isPresent() || currentJob.get().getTaskContext().getTask()
.getPeriod() > taskContext.getTask().getPeriod()) {
Optional<JobContext> optionalJob = taskContext.getNextJob();
if (optionalJob.isPresent()) {
if (currentJob.isPresent()) {
currentJob.get().setCurrentProcessor(null);
}
currentJob = optionalJob;
currentJob.get().setCurrentProcessor(this);
// System.out.println("Time " + t + ": " + this + " started job " + currentJob
// + " of task" + taskContext + "!");
return true;
} else {
return false;
}
}
return false;
}
@Override
public String toString() {
return "Processor " + processorId;
}
}
package mvd.jester.simulator.internals;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import mvd.jester.model.Segment;
/**
* Segment
*/
public class SegmentContext {
private final Segment segment;
private final Set<JobContext> jobs;
private final Set<TaskletContext> tasklets;
public SegmentContext(TaskContext taskContext, Segment segment) {
this.segment = segment;
jobs = new HashSet<>();
tasklets = new HashSet<>();
for (int j = 0; j < segment.getNumberOfJobs(); ++j) {
jobs.add(new JobContext(taskContext, this));
}
for (int t = 0; t < segment.getNumberOfTasklets(); ++t) {
tasklets.add(new TaskletContext(this));
}
}
/**
* @return the segment
*/
public Segment getSegment() {
return segment;
}
Optional<JobContext> getNextJob() {
return jobs.stream()
.filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime())
.findFirst();
}
@Override
public String toString() {
return "(nJobs=" + segment.getNumberOfJobs() + ", jobWcet=" + segment.getJobWcet() + ")";
}
}
package mvd.jester.simulator.internals;
import java.util.TreeSet;
import mvd.jester.priority.PriorityManager;
/**
* SortedTaskContextSet
*/
public class SortedTaskContextSet extends TreeSet<TaskContext> {
private static final long serialVersionUID = 4808544133562675597L;
public SortedTaskContextSet(PriorityManager priorityMananger) {
super((t1, t2) -> priorityMananger.compare(t1.getTask(), t2.getTask()));
}
}
package mvd.jester.simulator.internals;
import java.util.ArrayList;
import java.util.Optional;
import mvd.jester.model.Segment;
import mvd.jester.model.Task;
/**
* TaskContext
*/
public class TaskContext {
private final Task task;
private final ArrayList<SegmentContext> segments;
private final long deadline;
private int currentSegment;
private int segmentCounter;
public TaskContext(Task task, long timeStep) {
this.task = task;
this.segments = new ArrayList<>();
this.currentSegment = 0;
this.segmentCounter = 0;
this.deadline = timeStep + task.getDeadline();
for (Segment s : task.getSegments()) {
segments.add(new SegmentContext(this, s));
}
}
/**
* @return the task
*/
public Task getTask() {
return task;
}
/**
* @return the deadline
*/
public long getDeadline() {
return deadline;
}
public Optional<TaskContext> acceptNotification(long time) {
segmentCounter++;
if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfJobs()) {
currentSegment++;
segmentCounter = 0;
if (currentSegment >= segments.size()) {
// System.out.println("Time " + time + ": Task " + this + "finished!");
return Optional.of(this);
}
}
return Optional.empty();
}
public Optional<JobContext> getNextJob() {
if (currentSegment < segments.size()) {
Optional<JobContext> optionalJob = segments.get(currentSegment).getNextJob();
if (optionalJob.isPresent()) {
return optionalJob;
}
}
return Optional.empty();
}
@Override
public String toString() {
return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments="
+ segments.size() + ")";
}
}
package mvd.jester.simulator.internals;
/**
* Tasklet
*/
public class TaskletContext {
private final SegmentContext segment;
private final long wcet;
private long executionTime;
public TaskletContext(SegmentContext segment) {
this.segment = segment;
this.wcet = segment.getSegment().getTaskletWcet();
this.executionTime = 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