Commit ef2d8bd0 by Michael Schmid

refactoring of simulator for SchmidMottok

parent 19007890
package mvd.jester;
import java.io.File;
import mvd.jester.model.SystemSetup;
/**
......@@ -13,10 +12,11 @@ public class App {
TestEnvironment te = new TestEnvironment(builder, 40000);
// te.registerTestInterface(SchmidMottok.class);
te.registerTestPair(mvd.jester.tests.MaiaBertogna.class,
mvd.jester.simulator.MaiaBertogna.class);
te.registerTestPair(mvd.jester.tests.SchmidMottok.class,
mvd.jester.simulator.SchmidMottok.class);
te.runTests();
......
package mvd.jester.simulator;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import com.google.common.math.LongMath;
import java.util.TreeSet;
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;
import mvd.jester.simulator.internals.TaskContextInterface;
/**
......@@ -29,10 +29,49 @@ public abstract class AbstractSimulator implements SimulatorInterface {
processors.add(new ProcessorContext(i));
}
this.hyperPeriod = systemSetup.getTasks().last().getPeriod() * 10;
// LongMath.pow(systemSetup.getTasks().last().getPeriod(), 2);
}
protected void init() {
protected abstract boolean releaseTasks(long timeStep);
@Override
public boolean runSimulation() {
init();
for (int t = 0; t < hyperPeriod; ++t) {
if (!releaseTasks(t)) {
return false;
}
Set<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 (TaskContextInterface tc : readyTasks) {
if (p.acceptTask(tc, t)) {
break;
}
}
}
for (ProcessorContext p : processors) {
Optional<TaskContextInterface> optionalTc = p.updateExecution(t);
if (optionalTc.isPresent()) {
TaskContextInterface tc = optionalTc.get();
if (t >= tc.getDeadline()) {
return false;
}
readyTasks.remove(optionalTc.get());
}
}
}
return true;
}
private void init() {
this.readyTasks.clear();
for (ProcessorContext p : processors) {
p.setJob(null);
......@@ -40,15 +79,6 @@ public abstract class AbstractSimulator implements SimulatorInterface {
this.hyperPeriod = systemSetup.getTasks().last().getPeriod() * 10;
}
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;
import mvd.jester.model.Task;
import mvd.jester.simulator.internals.maiabertogna.TaskContext;
/**
* MaiaBertogna
......@@ -17,39 +14,14 @@ public class MaiaBertogna extends AbstractSimulator {
}
@Override
public boolean runSimulation() {
init();
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());
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 mvd.jester.model.SystemSetup;
import mvd.jester.model.Task;
import mvd.jester.simulator.internals.schmidmottok.TaskContext;
/**
* SchmidMottok
*/
public class SchmidMottok extends AbstractSimulator {
SchmidMottok(SystemSetup systemSetup) {
public SchmidMottok(SystemSetup systemSetup) {
super(systemSetup);
}
@Override
public boolean runSimulation() {
return false;
protected boolean releaseTasks(long timeStep) {
for (Task t : systemSetup.getTasks()) {
if (timeStep % t.getPeriod() == 0) {
TaskContext tc = new TaskContext(t, timeStep);
if (!readyTasks.add(tc)) {
return false;
}
// System.out.println("Time " + timeStep + ": " + "Task " + tc + "activated!");
}
}
return true;
}
@Override
public String getName() {
return "SchmidMottok";
......
package mvd.jester.simulator.internals;
import java.util.Optional;
/**
* JobContextInterface
*/
public interface JobContextInterface {
public Optional<TaskContextInterface> updateExecution(long time);
public boolean checkExecutionTime();
public void setCurrentProcessor(ProcessorContext processor);
public Optional<ProcessorContext> getCurrentProcessor();
public TaskContextInterface getTaskContext();
}
......@@ -7,7 +7,7 @@ import java.util.Optional;
*/
public class ProcessorContext {
private Optional<JobContext> currentJob;
private Optional<JobContextInterface> currentJob;
private final long processorId;
public ProcessorContext(long processorId) {
......@@ -15,18 +15,18 @@ public class ProcessorContext {
this.processorId = processorId;
}
public void setJob(JobContext job) {
public void setJob(JobContextInterface job) {
this.currentJob = Optional.ofNullable(job);
}
/**
* @return the currentJob
*/
public Optional<JobContext> getJob() {
public Optional<JobContextInterface> getJob() {
return currentJob;
}
public Optional<TaskContext> updateExecution(long time) {
public Optional<TaskContextInterface> updateExecution(long time) {
if (currentJob.isPresent()) {
return currentJob.get().updateExecution(time);
}
......@@ -35,10 +35,10 @@ public class ProcessorContext {
}
public boolean acceptTask(TaskContext taskContext, int t) {
public boolean acceptTask(TaskContextInterface taskContext, int t) {
if (!currentJob.isPresent() || currentJob.get().getTaskContext().getTask()
.getPeriod() > taskContext.getTask().getPeriod()) {
Optional<JobContext> optionalJob = taskContext.getNextJob();
Optional<JobContextInterface> optionalJob = taskContext.getNextJob();
if (optionalJob.isPresent()) {
if (currentJob.isPresent()) {
......@@ -46,7 +46,7 @@ public class ProcessorContext {
}
currentJob = optionalJob;
currentJob.get().setCurrentProcessor(this);
// System.out.println("Time " + t + ": " + this + " started job " + currentJob
// System.out.println("Time " + t + ": " + this + " started job " + currentJob.get()
// + " of task" + taskContext + "!");
return true;
} else {
......
......@@ -6,7 +6,7 @@ import mvd.jester.priority.PriorityManager;
/**
* SortedTaskContextSet
*/
public class SortedTaskContextSet extends TreeSet<TaskContext> {
public class SortedTaskContextSet extends TreeSet<TaskContextInterface> {
private static final long serialVersionUID = 4808544133562675597L;
......
package mvd.jester.simulator.internals;
import java.util.Optional;
import mvd.jester.model.Task;
/**
* TaskContextInterface
*/
public interface TaskContextInterface {
public Task getTask();
public Optional<TaskContextInterface> acceptNotification();
public Optional<JobContextInterface> getNextJob();
public long getDeadline();
}
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;
}
}
package mvd.jester.simulator.internals;
package mvd.jester.simulator.internals.maiabertogna;
import java.util.Optional;
import mvd.jester.simulator.internals.JobContextInterface;
import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.TaskContextInterface;
/**
* Job
*
* @param <Job>
*/
public class JobContext {
public class JobContext implements JobContextInterface {
private final TaskContext taskContext;
private final SegmentContext segmentContext;
......@@ -24,7 +27,7 @@ public class JobContext {
this.executionTime = wcet;
}
public Optional<TaskContext> updateExecution(long time) {
public Optional<TaskContextInterface> updateExecution(long time) {
executionTime--;
if (executionTime == 0) {
......@@ -32,7 +35,7 @@ public class JobContext {
// + " finished execution of job " + this + "!");
currentProcessor.get().setJob(null);
currentProcessor = Optional.empty();
return taskContext.acceptNotification(time);
return taskContext.acceptNotification();
}
return Optional.empty();
......
package mvd.jester.simulator.internals;
package mvd.jester.simulator.internals.maiabertogna;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import mvd.jester.model.Segment;
import mvd.jester.simulator.internals.JobContextInterface;
/**
* Segment
*/
public class SegmentContext {
private final Segment segment;
private final Set<JobContext> jobs;
private final Set<TaskletContext> tasklets;
private final Set<JobContextInterface> jobs;
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));
}
}
......@@ -35,13 +30,12 @@ public class SegmentContext {
return segment;
}
Optional<JobContext> getNextJob() {
Optional<JobContextInterface> 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;
package mvd.jester.simulator.internals.maiabertogna;
import java.util.ArrayList;
import java.util.Optional;
import mvd.jester.model.Segment;
import mvd.jester.model.Task;
import mvd.jester.simulator.internals.JobContextInterface;
import mvd.jester.simulator.internals.TaskContextInterface;
/**
* TaskContext
*/
public class TaskContext {
public class TaskContext implements TaskContextInterface {
private final Task task;
private final ArrayList<SegmentContext> segments;
......@@ -43,7 +45,7 @@ public class TaskContext {
return deadline;
}
public Optional<TaskContext> acceptNotification(long time) {
public Optional<TaskContextInterface> acceptNotification() {
segmentCounter++;
if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfJobs()) {
......@@ -59,9 +61,9 @@ public class TaskContext {
return Optional.empty();
}
public Optional<JobContext> getNextJob() {
public Optional<JobContextInterface> getNextJob() {
if (currentSegment < segments.size()) {
Optional<JobContext> optionalJob = segments.get(currentSegment).getNextJob();
Optional<JobContextInterface> optionalJob = segments.get(currentSegment).getNextJob();
if (optionalJob.isPresent()) {
return optionalJob;
}
......
package mvd.jester.simulator.internals.schmidmottok;
import java.util.Optional;
import mvd.jester.simulator.internals.JobContextInterface;
import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.TaskContextInterface;
/**
* Job
*
* @param <Job>
*/
public class JobContext implements JobContextInterface {
private final TaskContext taskContext;
private final SegmentContext segmentContext;
private final long wcet;
private Optional<ProcessorContext> currentProcessor;
private Optional<TaskletContext> currentTasklet;
private long executionTime;
public JobContext(TaskContext taskContext, SegmentContext segmentContext) {
this.currentProcessor = Optional.empty();
this.currentTasklet = Optional.empty();
this.taskContext = taskContext;
this.segmentContext = segmentContext;
this.wcet = segmentContext.getSegment().getJobWcet();
this.executionTime = wcet;
}
public Optional<TaskContextInterface> updateExecution(long time) {
if (!currentTasklet.isPresent()) {
currentTasklet = segmentContext.getNextTasklet();
// if (currentTasklet.isPresent()) {
// System.out.println("Time " + time + ": Job " + this + " started executing tasklet "
// + currentTasklet.get() + " on Processor " + currentProcessor.get());
// }
}
if (currentTasklet.isPresent()) {
currentTasklet.get().setCurrentJob(this);
return currentTasklet.get().updateExecution();
} else {
currentProcessor.get().setJob(null);
currentProcessor = Optional.empty();
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;
}
/**
* @param currentTasklet the currentTasklet to set
*/
public void setCurrentTasklet(TaskletContext currentTasklet) {
this.currentTasklet = Optional.ofNullable(currentTasklet);
}
/**
* @return the segmentContext
*/
public SegmentContext getSegmentContext() {
return segmentContext;
}
/**
* @return the taskContext
*/
public TaskContext getTaskContext() {
return taskContext;
}
@Override
public String toString() {
return "(of task=" + taskContext + ")";
}
}
package mvd.jester.simulator.internals.schmidmottok;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import mvd.jester.model.Segment;
import mvd.jester.simulator.internals.JobContextInterface;
/**
* Segment
*/
public class SegmentContext {
private final Segment segment;
private final Set<JobContextInterface> 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 j = 0; j < segment.getNumberOfTasklets(); ++j) {
tasklets.add(new TaskletContext(taskContext, this));
}
}
/**
* @return the segment
*/
public Segment getSegment() {
return segment;
}
Optional<JobContextInterface> getNextJob() {
return jobs.stream()
.filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime())
.findFirst();
}
Optional<TaskletContext> getNextTasklet() {
return tasklets.stream()
.filter(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()).findFirst();
}
@Override
public String toString() {
return "(nJobs=" + segment.getNumberOfJobs() + ", nTasklets="
+ segment.getNumberOfTasklets() + ", taskletWcet=" + segment.getTaskletWcet() + ")";
}
}
package mvd.jester.simulator.internals.schmidmottok;
import java.util.ArrayList;
import java.util.Optional;
import mvd.jester.model.Segment;
import mvd.jester.model.Task;
import mvd.jester.simulator.internals.JobContextInterface;
import mvd.jester.simulator.internals.TaskContextInterface;
/**
* TaskContext
*/
public class TaskContext implements TaskContextInterface {
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<TaskContextInterface> acceptNotification() {
segmentCounter++;
if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfTasklets()) {
currentSegment++;
segmentCounter = 0;
if (currentSegment >= segments.size()) {
// System.out.println("Time " + time + ": Task " + this + "finished!");
return Optional.of(this);
}
}
return Optional.empty();
}
public Optional<JobContextInterface> getNextJob() {
if (currentSegment < segments.size()) {
Optional<JobContextInterface> 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.schmidmottok;
import java.util.Optional;
import mvd.jester.simulator.internals.TaskContextInterface;
/**
* Tasklet
*/
public class TaskletContext {
private final TaskContext taskContext;
private Optional<JobContext> currentJob;
private final long wcet;
private long executionTime;
public TaskletContext(TaskContext taskContext, SegmentContext segment) {
this.taskContext = taskContext;
this.wcet = segment.getSegment().getTaskletWcet();
this.executionTime = wcet;
currentJob = Optional.empty();
}
/**
* @return the currentJob
*/
public Optional<JobContext> getCurrentJob() {
return currentJob;
}
public void setCurrentJob(JobContext jobContext) {
currentJob = Optional.ofNullable(jobContext);
}
public Optional<TaskContextInterface> updateExecution() {
executionTime--;
if (executionTime == 0) {
currentJob.get().setCurrentTasklet(null);
currentJob = Optional.empty();
return taskContext.acceptNotification();
}
return Optional.empty();
}
public boolean checkExecutionTime() {
return executionTime > 0;
}
@Override
public String toString() {
return "(wcet=" + wcet + ", task=" + taskContext + ")";
}
}
package mvd.jester.tests;
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.utils.Logger;
/**
* TestEnvironment
*/
public class TestEnvironment {
private final long numberOfTaskSets;
private final SystemSetup systemSetup;
private final SystemSetup.Builder builder;
private final Set<Constructor<? extends AbstractTest>> abstractTests;
public TestEnvironment(SystemSetup.Builder builder, long numberOfTaskSets) {
this.numberOfTaskSets = numberOfTaskSets;
abstractTests = new HashSet<>();
this.builder = builder;
this.systemSetup = builder.build();
}
public TestEnvironment registerTestInterface(Class<? extends AbstractTest> abstractTest) {
try {
abstractTests.add(abstractTest.getConstructor(SystemSetup.class));
} catch (Exception e) {
System.out.println("Missing constructor!");
}
return this;
}
public void runTests() {
Set<AbstractTest> testCases = new HashSet<>();
Map<Long, Map<AbstractTest, Long>> results = new HashMap<>();
for (Constructor<? extends AbstractTest> t : abstractTests) {
try {
testCases.add(t.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++;
long roundedUtilization = (long) (utilization * 10);
for (AbstractTest t : testCases) {
if (t.runSchedulabilityCheck()) {
results.computeIfAbsent(roundedUtilization,
k -> new HashMap<AbstractTest, Long>())
.compute(t, (k, v) -> (v == null) ? 1 : v + 1);
}
}
builder.addTask(systemSetup);
utilization = this.systemSetup.getUtilization();
}
}
logResults(testCases, results);
}
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();
}
}
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