Commit 36080fd3 by Michael Schmid

first commit of scheduler

parent cfdd3254
...@@ -5,6 +5,8 @@ import java.util.List; ...@@ -5,6 +5,8 @@ import java.util.List;
import mvd.jester.model.DagTask; import mvd.jester.model.DagTask;
import mvd.jester.model.SystemManager; import mvd.jester.model.SystemManager;
import mvd.jester.model.SystemManager.DagTaskBuilder; import mvd.jester.model.SystemManager.DagTaskBuilder;
import mvd.jester.priority.RateMonotonic;
import mvd.jester.simulator.GlobalScheduler;
import mvd.jester.tests.AbstractTest; import mvd.jester.tests.AbstractTest;
import mvd.jester.tests.FonsecaNelis; import mvd.jester.tests.FonsecaNelis;
import mvd.jester.tests.MelaniButtazzo; import mvd.jester.tests.MelaniButtazzo;
...@@ -19,6 +21,11 @@ import mvd.jester.tests.TypeFunction.UnkownStructure; ...@@ -19,6 +21,11 @@ import mvd.jester.tests.TypeFunction.UnkownStructure;
*/ */
public class App { public class App {
public static void main(String[] args) { public static void main(String[] args) {
GlobalScheduler scheduler = new GlobalScheduler(new RateMonotonic(), 4);
DagTaskBuilder builder = new DagTaskBuilder().setNumberOfProcessors(4);
scheduler.schedule(builder.generateTaskSet(3), 10000);
// { // {
// SystemManager manager = new SystemManager(8); // SystemManager manager = new SystemManager(8);
// DagTaskBuilder builder = new DagTaskBuilder(); // DagTaskBuilder builder = new DagTaskBuilder();
...@@ -43,18 +50,18 @@ public class App { ...@@ -43,18 +50,18 @@ public class App {
// te.varyNumberOfProcessors(builder, tests, manager, 500); // te.varyNumberOfProcessors(builder, tests, manager, 500);
// } // }
{ // {
SystemManager manager = new SystemManager(8); // SystemManager manager = new SystemManager(8);
DagTaskBuilder builder = new DagTaskBuilder(); // DagTaskBuilder builder = new DagTaskBuilder();
TestEnvironment te = new TestEnvironment(); // TestEnvironment te = new TestEnvironment();
List<AbstractTest<DagTask>> tests = // List<AbstractTest<DagTask>> tests =
te.registerTests(Arrays.asList(new SchmidMottok(new UnkownStructure(), manager), // te.registerTests(Arrays.asList(new SchmidMottok(new UnkownStructure(), manager),
new SchmidMottok(new KownStructure(), manager), // new SchmidMottok(new KownStructure(), manager),
new MelaniButtazzo(manager), new FonsecaNelis(manager))); // new MelaniButtazzo(manager), new FonsecaNelis(manager)));
te.varyNumberOfTasks(builder, tests, 8, 500); // te.varyNumberOfTasks(builder, tests, 8, 500);
} // }
// { // {
// SystemManager manager = new SystemManager(8); // SystemManager manager = new SystemManager(8);
// DagTaskBuilder builder = new DagTaskBuilder(); // DagTaskBuilder builder = new DagTaskBuilder();
......
package mvd.jester.model; package mvd.jester.model;
public class SubtaskContext { public class SubtaskContext {
private long wcet; private long remainingExecutionTime;
private final Subtask job; private final Subtask subtask;
public SubtaskContext(final Subtask job) { public SubtaskContext(final Subtask subtask) {
this.wcet = job.getWcet(); this.remainingExecutionTime = subtask.getWcet();
this.job = job; this.subtask = subtask;
} }
/** /**
* @return the job * @return the job
*/ */
public Subtask getJob() { public Subtask getSubtask() {
return job; return subtask;
} }
/** /**
* @return the wcet * @return the wcet
*/ */
public long getWcet() { public long getRemainingExecutionTime() {
return wcet; return remainingExecutionTime;
} }
/** /**
* @param wcet the wcet to set * @param wcet the wcet to set
*/ */
public void setWcet(final long wcet) { public void setRemainingExecutionTime(final long wcet) {
this.wcet = wcet; this.remainingExecutionTime = wcet;
}
public void updateRemainingExecutionTime(final long time) {
this.remainingExecutionTime -= time;
} }
@Override
public String toString() {
return getSubtask() + ":" + getRemainingExecutionTime();
}
} }
...@@ -4,10 +4,7 @@ import java.util.Arrays; ...@@ -4,10 +4,7 @@ import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import mvd.jester.model.Task; import mvd.jester.model.Task;
import mvd.jester.simulator.AbstractSimulator; import mvd.jester.simulator.model.JobContext;
import mvd.jester.simulator.ParallelSynchronous;
import mvd.jester.simulator.DynamicForkJoin;
import mvd.jester.simulator.internals.TaskContextInterface;
import mvd.jester.tests.AbstractTest; import mvd.jester.tests.AbstractTest;
import mvd.jester.tests.ChwaLee; import mvd.jester.tests.ChwaLee;
...@@ -18,8 +15,8 @@ public class EarliestDeadlineFirst implements PriorityManager { ...@@ -18,8 +15,8 @@ public class EarliestDeadlineFirst implements PriorityManager {
final static Set<Class<? extends AbstractTest<? extends Task>>> abstractTests = final static Set<Class<? extends AbstractTest<? extends Task>>> abstractTests =
new HashSet<>(Arrays.asList(ChwaLee.class)); new HashSet<>(Arrays.asList(ChwaLee.class));
final static Set<Class<? extends AbstractSimulator>> abstractSimulators = // final static Set<Class<? extends AbstractSimulator>> abstractSimulators =
new HashSet<>(Arrays.asList(ParallelSynchronous.class, DynamicForkJoin.class)); // new HashSet<>(Arrays.asList(ParallelSynchronous.class, DynamicForkJoin.class));
/** /**
* Compare the priority of two tasks according to the Rate Monotonic policy * Compare the priority of two tasks according to the Rate Monotonic policy
...@@ -35,7 +32,7 @@ public class EarliestDeadlineFirst implements PriorityManager { ...@@ -35,7 +32,7 @@ public class EarliestDeadlineFirst implements PriorityManager {
} }
@Override @Override
public int compare(TaskContextInterface t1, TaskContextInterface t2) { public int compare(JobContext t1, JobContext t2) {
return (int) (t1.getDeadline() - t2.getDeadline()); return (int) (t1.getDeadline() - t2.getDeadline());
} }
...@@ -49,15 +46,15 @@ public class EarliestDeadlineFirst implements PriorityManager { ...@@ -49,15 +46,15 @@ public class EarliestDeadlineFirst implements PriorityManager {
return abstractTests.contains(abstractTestClass); return abstractTests.contains(abstractTestClass);
} }
@Override // @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) { // public boolean hasSimulator(Class<? extends AbstractSimulator> abstractSimulatorClass) {
return abstractSimulators.contains(abstractSimulatorClass); // return abstractSimulators.contains(abstractSimulatorClass);
} // }
@Override @Override
public String getName() { public String getName() {
......
package mvd.jester.priority; package mvd.jester.priority;
import mvd.jester.model.Task; import mvd.jester.model.Task;
import mvd.jester.simulator.AbstractSimulator; // import mvd.jester.simulator.AbstractSimulator;
import mvd.jester.simulator.internals.TaskContextInterface; import mvd.jester.simulator.model.JobContext;
import mvd.jester.tests.AbstractTest; import mvd.jester.tests.AbstractTest;
/** /**
...@@ -12,15 +12,15 @@ public interface PriorityManager { ...@@ -12,15 +12,15 @@ public interface PriorityManager {
public int compare(Task t1, Task t2); public int compare(Task t1, Task t2);
public int compare(TaskContextInterface t1, TaskContextInterface t2); public int compare(JobContext t1, JobContext t2);
public boolean hasTest(AbstractTest<? extends Task> abstractTest); public boolean hasTest(AbstractTest<? extends Task> abstractTest);
public boolean hasTest(Class<? extends AbstractTest<? extends Task>> abstractTestClass); public boolean hasTest(Class<? extends AbstractTest<? extends Task>> abstractTestClass);
public boolean hasSimulator(AbstractSimulator abstractTest); // public boolean hasSimulator(AbstractSimulator abstractTest);
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractTestClass); // public boolean hasSimulator(Class<? extends AbstractSimulator> abstractTestClass);
public String getName(); public String getName();
......
...@@ -4,8 +4,8 @@ import java.util.Arrays; ...@@ -4,8 +4,8 @@ import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import mvd.jester.model.Task; import mvd.jester.model.Task;
import mvd.jester.simulator.AbstractSimulator; // import mvd.jester.simulator.AbstractSimulator;
import mvd.jester.simulator.internals.TaskContextInterface; import mvd.jester.simulator.model.JobContext;
import mvd.jester.tests.AbstractTest; import mvd.jester.tests.AbstractTest;
public class RateMonotonic implements PriorityManager { public class RateMonotonic implements PriorityManager {
...@@ -13,9 +13,9 @@ public class RateMonotonic implements PriorityManager { ...@@ -13,9 +13,9 @@ public class RateMonotonic implements PriorityManager {
final static Set<Class<? extends AbstractTest<? extends Task>>> abstractTests = final static Set<Class<? extends AbstractTest<? extends Task>>> abstractTests =
new HashSet<>(Arrays.asList(mvd.jester.tests.MaiaBertogna.class, new HashSet<>(Arrays.asList(mvd.jester.tests.MaiaBertogna.class,
mvd.jester.tests.SchmidMottok.class)); mvd.jester.tests.SchmidMottok.class));
final static Set<Class<? extends AbstractSimulator>> abstractSimulators = // final static Set<Class<? extends AbstractSimulator>> abstractSimulators =
new HashSet<>(Arrays.asList(mvd.jester.simulator.ParallelSynchronous.class, // new HashSet<>(Arrays.asList(mvd.jester.simulator.ParallelSynchronous.class,
mvd.jester.simulator.DynamicForkJoin.class)); // mvd.jester.simulator.DynamicForkJoin.class));
/** /**
* Compare the priority of two tasks according to the Rate Monotonic policy * Compare the priority of two tasks according to the Rate Monotonic policy
...@@ -30,8 +30,16 @@ public class RateMonotonic implements PriorityManager { ...@@ -30,8 +30,16 @@ public class RateMonotonic implements PriorityManager {
return Long.compare(t1.getPeriod(), t2.getPeriod()); return Long.compare(t1.getPeriod(), t2.getPeriod());
} }
/**
* Compare the priority of two tasks according to the Rate Monotonic policy
*
* @param t1 The first task context
* @param t2 The second task context
* @return 0 if both tasks have the same priority, negative number if the first task has a
* higher priority, positive number if the second task has a higher priority
*/
@Override @Override
public int compare(TaskContextInterface t1, TaskContextInterface t2) { public int compare(JobContext t1, JobContext t2) {
return Long.compare(t1.getTask().getPeriod(), t2.getTask().getPeriod()); return Long.compare(t1.getTask().getPeriod(), t2.getTask().getPeriod());
} }
...@@ -45,15 +53,15 @@ public class RateMonotonic implements PriorityManager { ...@@ -45,15 +53,15 @@ public class RateMonotonic implements PriorityManager {
return abstractTests.contains(abstractTestClass); return abstractTests.contains(abstractTestClass);
} }
@Override // @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) { // public boolean hasSimulator(Class<? extends AbstractSimulator> abstractSimulatorClass) {
return abstractSimulators.contains(abstractSimulatorClass); // return abstractSimulators.contains(abstractSimulatorClass);
} // }
@Override @Override
public String getName() { public String getName() {
......
package mvd.jester.simulator; // package mvd.jester.simulator;
import java.util.Comparator; // import java.util.Comparator;
import java.util.HashSet; // import java.util.HashSet;
import java.util.Set; // import java.util.Set;
import java.util.TreeSet; // import java.util.TreeSet;
import com.google.common.collect.TreeMultiset; // import com.google.common.collect.TreeMultiset;
import mvd.jester.model.SystemManager; // import mvd.jester.model.SystemManager;
import mvd.jester.priority.PriorityManager; // import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic; // import mvd.jester.priority.RateMonotonic;
import mvd.jester.TypeInterface; // import mvd.jester.TypeInterface;
import mvd.jester.info.SchedulingInfo; // import mvd.jester.info.SchedulingInfo;
import mvd.jester.simulator.internals.ProcessorContext; // import mvd.jester.simulator.model.ProcessorContext;
import mvd.jester.simulator.internals.TaskContextInterface; // import mvd.jester.simulator.internals.ITaskContext;
/** // /**
* AbstractSimulator // * AbstractSimulator
*/ // */
public abstract class AbstractSimulator implements SimulatorInterface, TypeInterface { // public abstract class AbstractSimulator implements SimulatorInterface, TypeInterface {
protected final SystemManager systemSetup; // protected final SystemManager systemSetup;
protected final Set<ProcessorContext> processors; // protected final Set<ProcessorContext> processors;
protected TreeMultiset<TaskContextInterface> readyTasks; // protected TreeMultiset<ITaskContext> readyTasks;
AbstractSimulator(SystemManager systemSetup) { // AbstractSimulator(SystemManager systemSetup) {
this.systemSetup = systemSetup; // this.systemSetup = systemSetup;
this.readyTasks = TreeMultiset.create((t1, t2) -> new RateMonotonic().compare(t1, t2)); // this.readyTasks = TreeMultiset.create((t1, t2) -> new RateMonotonic().compare(t1, t2));
processors = new HashSet<>(); // processors = new HashSet<>();
for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) { // for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) {
processors.add(new ProcessorContext(i)); // processors.add(new ProcessorContext(i));
} // }
} // }
protected abstract boolean releaseTasks(long timeStep); // protected abstract boolean releaseTasks(long timeStep);
@Override // @Override
public SchedulingInfo runSimulation(PriorityManager priorityManager) { // public SchedulingInfo runSimulation(PriorityManager priorityManager) {
// SchedulingInfo schedulingInfo = new SchedulingInfo(systemSetup.getParallelTaskRatio(), // // SchedulingInfo schedulingInfo = new SchedulingInfo(systemSetup.getParallelTaskRatio(),
// systemSetup.getUtilization()); // // systemSetup.getUtilization());
// long hyperPeriod = init(priorityManager); // // long hyperPeriod = init(priorityManager);
// for (int t = 0; t < hyperPeriod; ++t) { // // for (int t = 0; t < hyperPeriod; ++t) {
// if (!releaseTasks(t)) { // // if (!releaseTasks(t)) {
// throw new RuntimeException("Could not release a task. This should not happen!"); // // throw new RuntimeException("Could not release a task. This should not happen!");
// } // // }
// Set<ProcessorContext> sortedProcessors = sortProcessors(processors); // // Set<ProcessorContext> sortedProcessors = sortProcessors(processors);
// for (ProcessorContext p : sortedProcessors) { // // for (ProcessorContext p : sortedProcessors) {
// for (TaskContextInterface tc : readyTasks) { // // for (TaskContextInterface tc : readyTasks) {
// if (p.acceptTask(tc, t)) { // // if (p.acceptTask(tc, t)) {
// break; // // break;
// } // // }
// } // // }
// } // // }
// for (ProcessorContext p : processors) { // // for (ProcessorContext p : processors) {
// Optional<TaskContextInterface> optionalTc = p.updateExecution(t); // // Optional<TaskContextInterface> optionalTc = p.updateExecution(t);
// if (optionalTc.isPresent()) { // // if (optionalTc.isPresent()) {
// TaskContextInterface tc = optionalTc.get(); // // TaskContextInterface tc = optionalTc.get();
// if (t >= tc.getDeadline()) { // // if (t >= tc.getDeadline()) {
// TerminationInfo terminationInfo = // // TerminationInfo terminationInfo =
// new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t); // // new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t);
// schedulingInfo.addTerminationInfo(terminationInfo); // // schedulingInfo.addTerminationInfo(terminationInfo);
// EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!"); // // EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!");
// schedulingInfo.setFailedTerminationInfo(terminationInfo); // // schedulingInfo.setFailedTerminationInfo(terminationInfo);
// return schedulingInfo; // // return schedulingInfo;
// } // // }
// readyTasks.remove(optionalTc.get()); // // readyTasks.remove(optionalTc.get());
// } // // }
// } // // }
// } // // }
// return schedulingInfo; // // return schedulingInfo;
return null; // return null;
} // }
private long init(PriorityManager priorityManager) { // private long init(PriorityManager priorityManager) {
this.readyTasks = TreeMultiset.create((t1, t2) -> priorityManager.compare(t1, t2)); // this.readyTasks = TreeMultiset.create((t1, t2) -> priorityManager.compare(t1, t2));
for (ProcessorContext p : processors) { // for (ProcessorContext p : processors) {
p.setJob(null); // p.setJob(null);
} // }
return getHyperPeriod(); // return getHyperPeriod();
} // }
private Set<ProcessorContext> sortProcessors(Set<ProcessorContext> processors) { // private Set<ProcessorContext> sortProcessors(Set<ProcessorContext> processors) {
Set<ProcessorContext> sortedProcessors = new TreeSet<>(new ProcessorComparator()); // Set<ProcessorContext> sortedProcessors = new TreeSet<>(new ProcessorComparator());
processors.forEach(p -> sortedProcessors.add(p)); // processors.forEach(p -> sortedProcessors.add(p));
return sortedProcessors; // return sortedProcessors;
} // }
private long getHyperPeriod() { // private long getHyperPeriod() {
// return // // return
// systemSetup.getTasks().stream().max(Comparator.comparing(SynchronousTask::getPeriod)) // // systemSetup.getTasks().stream().max(Comparator.comparing(SynchronousTask::getPeriod))
// .get().getPeriod() * 10; // // .get().getPeriod() * 10;
return 10; // return 10;
} // }
private class ProcessorComparator implements Comparator<ProcessorContext> { // private class ProcessorComparator implements Comparator<ProcessorContext> {
@Override // @Override
public int compare(ProcessorContext p1, ProcessorContext p2) { // public int compare(ProcessorContext p1, ProcessorContext p2) {
if (!p1.getJob().isPresent()) { // if (!p1.getSubtask().isPresent()) {
return -1; // return -1;
} else if (!p2.getJob().isPresent()) { // } else if (!p2.getSubtask().isPresent()) {
return 1; // return 1;
} else { // } else {
long p1Period = p1.getJob().get().getTaskContext().getTask().getPeriod(); // long p1Period = p1.getSubtask().get().getJobContext().getTask().getPeriod();
long p2Period = p2.getJob().get().getTaskContext().getTask().getPeriod(); // long p2Period = p2.getSubtask().get().getJobContext().getTask().getPeriod();
if (p1Period == p2Period) { // if (p1Period == p2Period) {
return 1; // return 1;
} else { // } else {
return (int) (p2.getJob().get().getTaskContext().getTask().getPeriod() // return (int) (p2.getSubtask().get().getJobContext().getTask().getPeriod()
- p1.getJob().get().getTaskContext().getTask().getPeriod()); // - p1.getSubtask().get().getJobContext().getTask().getPeriod());
} // }
} // }
} // }
} // }
} // }
package mvd.jester.simulator; // package mvd.jester.simulator;
import mvd.jester.model.SystemManager; // import mvd.jester.model.SystemManager;
/** // /**
* SchmidMottok // * SchmidMottok
*/ // */
public class DynamicForkJoin extends AbstractSimulator { // public class DynamicForkJoin extends AbstractSimulator {
public DynamicForkJoin(SystemManager systemSetup) { // public DynamicForkJoin(SystemManager systemSetup) {
super(systemSetup); // super(systemSetup);
} // }
@Override // @Override
protected boolean releaseTasks(long timeStep) { // protected boolean releaseTasks(long timeStep) {
// // for (SynchronousTask t : systemSetup.getTasks()) { // // // for (SynchronousTask t : systemSetup.getTasks()) {
// if (timeStep % t.getPeriod() == 0) { // // if (timeStep % t.getPeriod() == 0) {
// TaskContext tc = new TaskContext(t, systemSetup.getNumberOfProcessors(), timeStep); // // TaskContext tc = new TaskContext(t, systemSetup.getNumberOfProcessors(), timeStep);
// if (!readyTasks.add(tc)) { // // if (!readyTasks.add(tc)) {
// EventPrinter // // EventPrinter
// .print("Time " + timeStep + ": Task " + tc + " could not be released!"); // // .print("Time " + timeStep + ": Task " + tc + " could not be released!");
// return false; // // return false;
// } // // }
// EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!"); // // EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!");
// } // // }
// } // // }
return true; // return true;
} // }
@Override // @Override
public String getName() { // public String getName() {
return "SchmidMottok"; // return "SchmidMottok";
} // }
} // }
package mvd.jester.simulator;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.jgrapht.Graphs;
import mvd.jester.model.DagTask;
import mvd.jester.model.Subtask;
import mvd.jester.priority.PriorityManager;
import mvd.jester.simulator.events.*;
import mvd.jester.simulator.exceptions.SchedulingException;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.JobContext;
import mvd.jester.simulator.model.ProcessorContext;
public class GlobalScheduler {
private final int nbProcessors;
private final PriorityManager priorityManager;
public GlobalScheduler(PriorityManager priorityManager, int nbProcessors) {
this.priorityManager = priorityManager;
this.nbProcessors = nbProcessors;
}
public void schedule(Set<DagTask> taskSet, long duration) {
SchedulingContext sc = new SchedulingContext(priorityManager, nbProcessors, duration);
taskSet.forEach(t -> sc.events.offer(new TaskReleasedEvent(0, t)));
while (!sc.events.isEmpty()) {
IEvent event = sc.events.poll();
updateExecution(sc, event.getTime());
handle(event, sc);
}
}
private void handle(IEvent event, SchedulingContext sc) {
event.log();
switch (event.getType()) {
case SUBTASK_ACTIVATED:
handleSubtaskActivated((SubtaskActivatedEvent) event, sc);
break;
case SUBTASK_COMPLETED:
handleSubtaskCompleted((SubtaskCompletedEvent) event, sc);
break;
case SUBTASK_CHECK_COMPLETED:
handleSubtaskCheckCompleted((SubtaskCheckCompletedEvent) event, sc);
break;
case SUBTASK_PREEMPTED:
handleSubtaskPreempted((SubtaskPreemptedEvent) event, sc);
break;
case SUBTASK_STARTED:
handleSubtaskStarted((SubtaskStartedEvent) event, sc);
break;
case SUBTASK_STOPPED:
handleSubtaskStopped((SubtaskStoppedEvent) event, sc);
break;
case JOB_ACTIVATED:
handleJobActivated((JobActivatedEvent) event, sc);
break;
case TASK_RELEASED:
handleTaskReleased((TaskReleasedEvent) event, sc);
break;
default:
throw new IllegalArgumentException(
event.getType() + " is not handled by " + this.getClass());
}
}
private void handleSubtaskActivated(SubtaskActivatedEvent event, SchedulingContext sc) {
Subtask subtask = event.getSubtask();
JobContext job = event.getJobContext();
sc.waitingQueue.offer(new ExtendedSubtaskContext(job, subtask));
updateAdmission(sc, event.getTime());
}
private void handleSubtaskCheckCompleted(SubtaskCheckCompletedEvent event,
SchedulingContext sc) {
ProcessorContext processor = event.getProcessor();
if (processor.isIdle() || !processor.getSubtask().get().equals(event.getSubtaskContext())) {
throw new SchedulingException(
processor + " should execute " + event.getSubtaskContext());
}
Optional<ExtendedSubtaskContext> context = processor.getSubtask();
if (context.isPresent() && context.get().getRemainingExecutionTime() == 0) {
sc.events.offer(new SubtaskStoppedEvent(event.getTime(), context.get(), processor));
}
}
private void handleSubtaskCompleted(SubtaskCompletedEvent event, SchedulingContext sc) {
ExtendedSubtaskContext subtask = event.getSubtaskContext();
JobContext job = subtask.getJobContext();
DagTask task = subtask.getJobContext().getTask();
List<Subtask> successor = Graphs.successorListOf(task.getJobDag(), subtask.getSubtask());
if (successor.isEmpty()) {
sc.events.offer(new JobCompletedEvent(event.getTime(), job));
updateAdmission(sc, event.getTime());
} else {
for (Subtask s : successor) {
sc.events.offer(new SubtaskActivatedEvent(event.getTime(), job, s));
}
}
}
private void handleSubtaskPreempted(SubtaskPreemptedEvent event, SchedulingContext sc) {
ProcessorContext processor = event.getProcessor();
long time = event.getTime();
sc.events.offer(new SubtaskStoppedEvent(time, event.getNextSubtask(), processor));
sc.events.offer(new SubtaskStartedEvent(time, event.getSubtaskContext(), processor));
}
private void handleSubtaskStarted(SubtaskStartedEvent event, SchedulingContext sc) {
long time = event.getTime();
ProcessorContext processor = event.getProcessor();
ExtendedSubtaskContext context = event.getSubtaskContext();
if (processor.accept(context, time)) {
sc.events.offer(new SubtaskCheckCompletedEvent(
time + context.getRemainingExecutionTime(), context, processor));
}
}
private void handleSubtaskStopped(SubtaskStoppedEvent event, SchedulingContext sc) {
ExtendedSubtaskContext context = event.getSubtaskContext();
ProcessorContext processor = event.getProcessor();
if (context.getRemainingExecutionTime() > 0) {
sc.waitingQueue.offer(context);
} else {
sc.events.offer(new SubtaskCompletedEvent(event.getTime(), context));
}
processor.free();
}
private void handleJobActivated(JobActivatedEvent event, SchedulingContext sc) {
JobContext job = event.getJobContext();
DagTask task = job.getTask();
long nextRelease = event.getTime() + task.getPeriod();
if (nextRelease < sc.duration) {
JobContext nextJob = new JobContext(task, nextRelease);
sc.events.offer(new JobActivatedEvent(nextRelease, nextJob));
}
sc.events.offer(new SubtaskActivatedEvent(event.getTime(), job, job.getSource()));
}
private void handleTaskReleased(TaskReleasedEvent event, SchedulingContext sc) {
DagTask task = event.getTask();
long release = event.getTime();
JobContext job = new JobContext(task, release);
sc.events.offer(new JobActivatedEvent(release, job));
}
private void updateAdmission(SchedulingContext sc, long time) {
for (ProcessorContext processor : sc.processors) {
if (processor.canAccept(sc.waitingQueue.peek(), priorityManager)) {
ExtendedSubtaskContext context = sc.waitingQueue.poll();
if (processor.isIdle()) {
sc.events.offer(new SubtaskStartedEvent(time, context, processor));
} else {
sc.events.offer(new SubtaskPreemptedEvent(time, processor.getSubtask().get(),
processor, context));
}
}
}
}
private void updateExecution(SchedulingContext sc, long time) {
for (ProcessorContext processor : sc.processors) {
processor.update(time);
}
}
private class SchedulingContext {
private final EventQueue events;
private final Set<ProcessorContext> processors;
private final WaitQueue waitingQueue;
private final long duration;
private SchedulingContext(PriorityManager priorityManager, int nbProcessors,
long duration) {
this.events = new EventQueue(priorityManager);
this.waitingQueue = new WaitQueue(priorityManager);
this.processors = new HashSet<>();
for (int m = 0; m < nbProcessors; ++m) {
processors.add(new ProcessorContext(m));
}
this.duration = duration;
}
}
}
package mvd.jester.simulator; // package mvd.jester.simulator;
import mvd.jester.model.SystemManager; // import mvd.jester.model.SystemManager;
/** // /**
* MaiaBertogna // * MaiaBertogna
*/ // */
public class ParallelSynchronous extends AbstractSimulator { // public class ParallelSynchronous extends AbstractSimulator {
public ParallelSynchronous(SystemManager systemSetup) { // public ParallelSynchronous(SystemManager systemSetup) {
super(systemSetup); // super(systemSetup);
} // }
@Override // @Override
protected boolean releaseTasks(long timeStep) { // protected boolean releaseTasks(long timeStep) {
// for (SynchronousTask t : systemSetup.getTasks()) { // // for (SynchronousTask t : systemSetup.getTasks()) {
// if (timeStep % t.getPeriod() == 0) { // // if (timeStep % t.getPeriod() == 0) {
// TaskContext tc = new TaskContext(t, timeStep); // // TaskContext tc = new TaskContext(t, timeStep);
// if (!readyTasks.add(tc)) { // // if (!readyTasks.add(tc)) {
// EventPrinter // // EventPrinter
// .print("Time " + timeStep + ": Task " + tc + " could not be released!"); // // .print("Time " + timeStep + ": Task " + tc + " could not be released!");
// return false; // // return false;
// } // // }
// EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!"); // // EventPrinter.print("Time " + timeStep + ": Task " + tc + " released!");
// } // // }
// } // // }
return true; // return true;
} // }
@Override // @Override
public String getName() { // public String getName() {
return "MaiaBertogna"; // return "MaiaBertogna";
} // }
} // }
package mvd.jester.simulator;
import java.util.PriorityQueue;
import mvd.jester.priority.PriorityManager;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
public class WaitQueue extends PriorityQueue<ExtendedSubtaskContext> {
private static final long serialVersionUID = -4968780596887106984L;
public WaitQueue(PriorityManager priorityManager) {
super((jc1, jc2) -> priorityManager.compare(jc1.getJobContext(), jc2.getJobContext()));
}
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.JobContext;
public abstract class AbstractContextEvent extends AbstractSubtaskEvent implements ISubtaskEvent {
private final ExtendedSubtaskContext subtask;
protected AbstractContextEvent(EventType type, long time, ExtendedSubtaskContext subtask,
JobContext jobContext) {
super(type, time, jobContext);
this.subtask = subtask;
}
@Override
public ExtendedSubtaskContext getSubtaskContext() {
return subtask;
}
}
package mvd.jester.simulator.events;
public abstract class AbstractEvent implements IEvent {
private final EventType type;
private final long time;
protected AbstractEvent(EventType type, long time) {
this.type = type;
this.time = time;
}
@Override
public long getTime() {
return time;
}
@Override
public EventType getType() {
return type;
}
@Override
public final void log() {
System.out.printf("[%19s] > %s\n", getTime(), getLoggingMessage());
}
protected abstract String getLoggingMessage();
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.JobContext;
public abstract class AbstractSubtaskEvent extends AbstractEvent {
private final JobContext jobContext;
protected AbstractSubtaskEvent(EventType type, long time, JobContext job) {
super(type, time);
this.jobContext = job;
}
/**
* @return the jobContext
*/
public JobContext getJobContext() {
return jobContext;
}
}
package mvd.jester.simulator.events;
import java.util.Comparator;
import java.util.PriorityQueue;
import mvd.jester.priority.PriorityManager;
public class EventQueue extends PriorityQueue<IEvent> {
/**
*
*/
private static final long serialVersionUID = -6221675577222053574L;
public EventQueue(final PriorityManager priorityManager) {
super(new EventComparator(priorityManager));
}
private static class EventComparator implements Comparator<IEvent> {
private final PriorityManager priorityManager;
private EventComparator(final PriorityManager priorityManager) {
this.priorityManager = priorityManager;
}
/**
* Compare two events. The following comparisons are made: 1. time of the events 2. priority
* of the events (according to the event enumeration order) 3. priority of the jobs
* (according to the scheduling priority policy)
*
* @param e1 The first event.
* @param e2 The second event.
* @return 0 if events are considered equivalent, negative number if the first event is
* prior to the second one and positive number if the first event is after the
* second one.
*/
@Override
public int compare(final IEvent e1, final IEvent e2) {
final long timeDiff = e1.getTime() - e2.getTime();
if (timeDiff != 0) {
return (int) timeDiff;
}
final int ordDiff = e1.getType().ordinal() - e2.getType().ordinal();
if (ordDiff != 0) {
return ordDiff;
}
if (!(e1 instanceof ISubtaskEvent && e2 instanceof ISubtaskEvent)) {
return 0;
}
return priorityManager.compare(((ISubtaskEvent) e1).getJobContext(),
((ISubtaskEvent) e2).getJobContext());
}
}
}
package mvd.jester.simulator.events;
public enum EventType {
TASK_RELEASED,
JOB_COMPLETED,
JOB_ACTIVATED,
SUBTASK_CHECK_COMPLETED,
SUBTASK_PREEMPTED,
SUBTASK_COMPLETED,
SUBTASK_STOPPED,
SUBTASK_STARTED,
SUBTASK_ACTIVATED;
}
package mvd.jester.simulator.events;
public interface IEvent {
long getTime();
EventType getType();
void log();
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.JobContext;
public interface ISubtaskEvent extends IEvent {
public ExtendedSubtaskContext getSubtaskContext();
public JobContext getJobContext();
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.JobContext;
public class JobActivatedEvent extends AbstractEvent {
private JobContext job;
public JobActivatedEvent(long time, JobContext job) {
super(EventType.JOB_ACTIVATED, time);
this.job = job;
}
/**
* @return the job
*/
public JobContext getJobContext() {
return job;
}
@Override
protected String getLoggingMessage() {
return "Job " + job + " released";
}
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.JobContext;
public class JobCompletedEvent extends AbstractEvent {
private JobContext job;
public JobCompletedEvent(long time, JobContext job) {
super(EventType.JOB_COMPLETED, time);
this.job = job;
}
/**
* @return the job
*/
public JobContext getJobContext() {
return job;
}
@Override
protected String getLoggingMessage() {
return "Job " + job + " completed";
}
}
package mvd.jester.simulator.events;
import mvd.jester.model.Subtask;
import mvd.jester.simulator.model.JobContext;
public class SubtaskActivatedEvent extends AbstractEvent {
private final JobContext job;
private final Subtask subtask;
public SubtaskActivatedEvent(final long time, final JobContext job, final Subtask subtask) {
super(EventType.SUBTASK_ACTIVATED, time);
this.job = job;
this.subtask = subtask;
}
/**
* @return the job
*/
public JobContext getJobContext() {
return job;
}
/**
* @return the subtask
*/
public Subtask getSubtask() {
return subtask;
}
@Override
protected String getLoggingMessage() {
return "Subtask " + getSubtask() + " released";
}
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.ProcessorContext;
public class SubtaskCheckCompletedEvent extends AbstractContextEvent {
private final ProcessorContext processor;
public SubtaskCheckCompletedEvent(final long time, final ExtendedSubtaskContext subtask,
final ProcessorContext processor) {
super(EventType.SUBTASK_CHECK_COMPLETED, time, subtask, subtask.getJobContext());
this.processor = processor;
}
/**
* @return the processor
*/
public ProcessorContext getProcessor() {
return processor;
}
@Override
protected String getLoggingMessage() {
return "Subtask " + getSubtaskContext() + " maybe completed on " + getProcessor();
}
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
public class SubtaskCompletedEvent extends AbstractContextEvent {
public SubtaskCompletedEvent(long time, ExtendedSubtaskContext subtask) {
super(EventType.SUBTASK_COMPLETED, time, subtask, subtask.getJobContext());
}
@Override
protected String getLoggingMessage() {
return "Subtask " + getSubtaskContext() + " completed";
}
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.ProcessorContext;
public class SubtaskPreemptedEvent extends AbstractContextEvent {
private ProcessorContext processor;
private ExtendedSubtaskContext nextSubtask;
public SubtaskPreemptedEvent(long time, ExtendedSubtaskContext subtask,
ProcessorContext processor, ExtendedSubtaskContext nextSubtask) {
super(EventType.SUBTASK_PREEMPTED, time, subtask, subtask.getJobContext());
this.processor = processor;
this.nextSubtask = nextSubtask;
}
/**
* @return the processor
*/
public ProcessorContext getProcessor() {
return processor;
}
/**
* @return the nextSubtask
*/
public ExtendedSubtaskContext getNextSubtask() {
return nextSubtask;
}
@Override
protected String getLoggingMessage() {
return "Subtask " + getSubtaskContext() + " preempted by " + getNextSubtask();
}
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.ProcessorContext;
public class SubtaskStartedEvent extends AbstractContextEvent {
private final ProcessorContext processor;
public SubtaskStartedEvent(final long time, final ExtendedSubtaskContext subtask,
final ProcessorContext processor) {
super(EventType.SUBTASK_STARTED, time, subtask, subtask.getJobContext());
this.processor = processor;
}
/**
* @return the processor
*/
public ProcessorContext getProcessor() {
return processor;
}
@Override
protected String getLoggingMessage() {
return "Subtask " + getSubtaskContext() + " started execution on " + getProcessor();
}
}
package mvd.jester.simulator.events;
import mvd.jester.simulator.model.ExtendedSubtaskContext;
import mvd.jester.simulator.model.ProcessorContext;
public class SubtaskStoppedEvent extends AbstractContextEvent {
private ProcessorContext processor;
public SubtaskStoppedEvent(long time, ExtendedSubtaskContext subtask,
ProcessorContext processor) {
super(EventType.SUBTASK_STOPPED, time, subtask, subtask.getJobContext());
this.processor = processor;
}
/**
* @return the processor
*/
public ProcessorContext getProcessor() {
return processor;
}
@Override
protected String getLoggingMessage() {
return "Subtask " + getSubtaskContext() + " stopped on " + getProcessor();
}
}
package mvd.jester.simulator.events;
import mvd.jester.model.DagTask;
public class TaskReleasedEvent extends AbstractEvent {
private final DagTask task;
public TaskReleasedEvent(long time, DagTask task) {
super(EventType.TASK_RELEASED, time);
this.task = task;
}
public DagTask getTask() {
return task;
}
@Override
public String getLoggingMessage() {
return "task " + getTask() + " started";
}
}
package mvd.jester.simulator.exceptions;
public class DeadlineMissedException extends RuntimeException {
private static final long serialVersionUID = -7635316944888221110L;
public DeadlineMissedException(String message) {
super(message);
}
}
package mvd.jester.simulator.exceptions;
public class ExecutionOverrunException extends RuntimeException {
private static final long serialVersionUID = -899332907791579362L;
public ExecutionOverrunException(String message) {
super(message);
}
}
package mvd.jester.simulator.exceptions;
public class SchedulingException extends RuntimeException {
private static final long serialVersionUID = -7851284137097347264L;
public SchedulingException(String message) {
super(message);
}
}
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();
public boolean prepareJob(long time);
}
package mvd.jester.simulator.internals;
import java.util.Optional;
import mvd.jester.simulator.EventPrinter;
/**
* Processor
*/
public class ProcessorContext {
private Optional<JobContextInterface> currentJob;
private final long processorId;
public ProcessorContext(long processorId) {
currentJob = Optional.empty();
this.processorId = processorId;
}
public void setJob(JobContextInterface job) {
this.currentJob = Optional.ofNullable(job);
}
/**
* @return the currentJob
*/
public Optional<JobContextInterface> getJob() {
return currentJob;
}
public Optional<TaskContextInterface> updateExecution(long time) {
if (currentJob.isPresent()) {
return currentJob.get().updateExecution(time);
}
return Optional.empty();
}
public boolean acceptTask(TaskContextInterface taskContext, int t) {
if (!currentJob.isPresent() || currentJob.get().getTaskContext().getTask()
.getPeriod() > taskContext.getTask().getPeriod()) {
Optional<JobContextInterface> optionalJob = taskContext.getNextJob();
if (optionalJob.isPresent()) {
if (!optionalJob.get().prepareJob(t)) {
return false;
}
if (currentJob.isPresent()) {
currentJob.get().setCurrentProcessor(null);
}
currentJob = optionalJob;
currentJob.get().setCurrentProcessor(this);
EventPrinter.print(
"Time " + t + ": " + this + " started job " + currentJob.get() + "!");
return true;
}
}
return false;
}
@Override
public String toString() {
return "Processor " + processorId;
}
}
package mvd.jester.simulator.internals; // package mvd.jester.simulator.internals;
import java.util.TreeSet; // import java.util.TreeSet;
import mvd.jester.priority.PriorityManager; // import mvd.jester.priority.PriorityManager;
/** // /**
* SortedTaskContextSet // * SortedTaskContextSet
*/ // */
public class SortedTaskContextSet extends TreeSet<TaskContextInterface> { // public class SortedTaskContextSet extends TreeSet<ITaskContext> {
private static final long serialVersionUID = 4808544133562675597L; // private static final long serialVersionUID = 4808544133562675597L;
public SortedTaskContextSet(PriorityManager priorityMananger) { // public SortedTaskContextSet(PriorityManager priorityMananger) {
super((t1, t2) -> priorityMananger.compare(t1, t2)); // super((t1, t2) -> priorityMananger.compare(t1, t2));
} // }
} // }
package mvd.jester.simulator.internals.dynamicforkjoin; // package mvd.jester.simulator.internals.dynamicforkjoin;
import java.util.Optional; // import java.util.Optional;
import mvd.jester.simulator.EventPrinter; // import mvd.jester.simulator.EventPrinter;
import mvd.jester.simulator.internals.JobContextInterface; // import mvd.jester.simulator.internals.ISubtaskContext;
import mvd.jester.simulator.internals.ProcessorContext; // import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.TaskContextInterface; // import mvd.jester.simulator.internals.ITaskContext;
/** // /**
* Job // * Job
* // *
* @param <Job> // * @param <Job>
*/ // */
public class JobContext implements JobContextInterface { // public class JobContext implements ISubtaskContext {
private final TaskContext taskContext; // private final TaskContext taskContext;
private final SegmentContext segmentContext; // private final SegmentContext segmentContext;
private final long wcet; // private final long wcet;
private Optional<ProcessorContext> currentProcessor; // private Optional<ProcessorContext> currentProcessor;
private Optional<TaskletContext> currentTasklet; // private Optional<TaskletContext> currentTasklet;
public JobContext(TaskContext taskContext, SegmentContext segmentContext) { // public JobContext(TaskContext taskContext, SegmentContext segmentContext) {
this.currentProcessor = Optional.empty(); // this.currentProcessor = Optional.empty();
this.currentTasklet = Optional.empty(); // this.currentTasklet = Optional.empty();
this.taskContext = taskContext; // this.taskContext = taskContext;
this.segmentContext = segmentContext; // this.segmentContext = segmentContext;
this.wcet = segmentContext.getSegment().getJobWcet(); // this.wcet = segmentContext.getSegment().getJobWcet();
} // }
public Optional<TaskContextInterface> updateExecution(long time) { // public Optional<ITaskContext> updateExecution(long time) {
boolean jobIsIdle = true; // boolean jobIsIdle = true;
if (currentTasklet.isPresent()) { // if (currentTasklet.isPresent()) {
jobIsIdle = currentTasklet.get().updateExecution(time); // jobIsIdle = currentTasklet.get().updateExecution(time);
} // }
if (jobIsIdle) { // if (jobIsIdle) {
currentTasklet = segmentContext.getNextTasklet(); // currentTasklet = segmentContext.getNextTasklet();
Optional<TaskContextInterface> tc = taskContext.acceptNotification(time); // Optional<ITaskContext> tc = taskContext.acceptNotification(time);
if (currentTasklet.isPresent()) { // if (currentTasklet.isPresent()) {
EventPrinter.print("Time " + time + ": Job " + this + " started executing tasklet " // EventPrinter.print("Time " + time + ": Job " + this + " started executing tasklet "
+ currentTasklet.get() + " on Processor " + currentProcessor.get()); // + currentTasklet.get() + " on Processor " + currentProcessor.get());
currentTasklet.get().setCurrentJob(this); // currentTasklet.get().setCurrentJob(this);
} else { // } else {
if (currentProcessor.isPresent()) { // if (currentProcessor.isPresent()) {
currentProcessor.get().setJob(null); // currentProcessor.get().setJob(null);
} // }
currentProcessor = Optional.empty(); // currentProcessor = Optional.empty();
return tc; // return tc;
} // }
} // }
return Optional.empty(); // return Optional.empty();
} // }
public boolean checkExecutionTime() { // public boolean checkExecutionTime() {
if (currentTasklet.isPresent()) { // if (currentTasklet.isPresent()) {
return currentTasklet.get().checkExecutionTime(); // return currentTasklet.get().checkExecutionTime();
} // }
return false; // return false;
} // }
/** // /**
* @return the wcet // * @return the wcet
*/ // */
public long getWcet() { // public long getWcet() {
return wcet; // return wcet;
} // }
/** // /**
* @param processor the currentProcessor to set // * @param processor the currentProcessor to set
*/ // */
public void setCurrentProcessor(ProcessorContext processor) { // public void setCurrentProcessor(ProcessorContext processor) {
this.currentProcessor = Optional.ofNullable(processor); // this.currentProcessor = Optional.ofNullable(processor);
} // }
/** // /**
* @return the currentProcessor // * @return the currentProcessor
*/ // */
public Optional<ProcessorContext> getCurrentProcessor() { // public Optional<ProcessorContext> getCurrentProcessor() {
return currentProcessor; // return currentProcessor;
} // }
/** // /**
* @param currentTasklet the currentTasklet to set // * @param currentTasklet the currentTasklet to set
*/ // */
public void setCurrentTasklet(TaskletContext currentTasklet) { // public void setCurrentTasklet(TaskletContext currentTasklet) {
this.currentTasklet = Optional.ofNullable(currentTasklet); // this.currentTasklet = Optional.ofNullable(currentTasklet);
} // }
/** // /**
* @return the segmentContext // * @return the segmentContext
*/ // */
public SegmentContext getSegmentContext() { // public SegmentContext getSegmentContext() {
return segmentContext; // return segmentContext;
} // }
/** // /**
* @return the taskContext // * @return the taskContext
*/ // */
public TaskContext getTaskContext() { // public TaskContext getTaskContext() {
return taskContext; // return taskContext;
} // }
@Override // @Override
public String toString() { // public String toString() {
return "(of task=" + taskContext + ")"; // return "(of task=" + taskContext + ")";
} // }
@Override // @Override
public boolean prepareJob(long time) { // public boolean prepareJob(long time) {
if (!currentTasklet.isPresent()) { // if (!currentTasklet.isPresent()) {
currentTasklet = segmentContext.getNextTasklet(); // currentTasklet = segmentContext.getNextTasklet();
if (currentTasklet.isPresent()) { // if (currentTasklet.isPresent()) {
currentTasklet.get().setCurrentJob(this); // currentTasklet.get().setCurrentJob(this);
// EventPrinter.print("Time " + time + ": Job " + this + " started executing // // EventPrinter.print("Time " + time + ": Job " + this + " started executing
// tasklet" // // tasklet"
// + currentTasklet.get()); // // + currentTasklet.get());
return true; // return true;
} else { // } else {
return false; // return false;
} // }
} // }
return true; // return true;
} // }
} // }
package mvd.jester.simulator.internals.dynamicforkjoin; // package mvd.jester.simulator.internals.dynamicforkjoin;
import java.util.HashSet; // import java.util.HashSet;
import java.util.Optional; // import java.util.Optional;
import java.util.Set; // import java.util.Set;
import mvd.jester.model.Segment; // import mvd.jester.model.Segment;
import mvd.jester.simulator.internals.JobContextInterface; // import mvd.jester.simulator.internals.ISubtaskContext;
/** // /**
* Segment // * Segment
*/ // */
public class SegmentContext { // public class SegmentContext {
private final Segment segment; // private final Segment segment;
private final Set<JobContextInterface> jobs; // private final Set<ISubtaskContext> jobs;
private final Set<TaskletContext> tasklets; // private final Set<TaskletContext> tasklets;
public SegmentContext(TaskContext taskContext, Segment segment, long numberOfProcessors) { // public SegmentContext(TaskContext taskContext, Segment segment, long numberOfProcessors) {
this.segment = segment; // this.segment = segment;
jobs = new HashSet<>(); // jobs = new HashSet<>();
tasklets = new HashSet<>(); // tasklets = new HashSet<>();
long numberOfJobs = segment.getNumberOfJobs() > numberOfProcessors ? numberOfProcessors // long numberOfJobs = segment.getNumberOfJobs() > numberOfProcessors ? numberOfProcessors
: segment.getNumberOfJobs(); // : segment.getNumberOfJobs();
for (int j = 0; j < numberOfJobs; ++j) { // for (int j = 0; j < numberOfJobs; ++j) {
jobs.add(new JobContext(taskContext, this)); // jobs.add(new JobContext(taskContext, this));
} // }
// for (int j = 0; j < segment.getNumberOfTasklets(); ++j) { // // for (int j = 0; j < segment.getNumberOfTasklets(); ++j) {
// tasklets.add(new TaskletContext(taskContext, this)); // // tasklets.add(new TaskletContext(taskContext, this));
// } // // }
} // }
/** // /**
* @return the segment // * @return the segment
*/ // */
public Segment getSegment() { // public Segment getSegment() {
return segment; // return segment;
} // }
public long getNumberOfJobs() { // public long getNumberOfJobs() {
return jobs.size(); // return jobs.size();
} // }
public Optional<JobContextInterface> getNextJob() { // public Optional<ISubtaskContext> getNextJob() {
boolean taskletAvailable = tasklets.stream() // boolean taskletAvailable = tasklets.stream()
.anyMatch(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()); // .anyMatch(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime());
boolean jobNotFinished = jobs.stream() // boolean jobNotFinished = jobs.stream()
.anyMatch(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime()); // .anyMatch(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime());
if (jobNotFinished) { // if (jobNotFinished) {
return jobs.stream() // return jobs.stream()
.filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime()) // .filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime())
.findFirst(); // .findFirst();
} else if (taskletAvailable) { // } else if (taskletAvailable) {
return jobs.stream() // return jobs.stream()
.filter(j -> !j.getCurrentProcessor().isPresent() && !j.checkExecutionTime()) // .filter(j -> !j.getCurrentProcessor().isPresent() && !j.checkExecutionTime())
.findFirst(); // .findFirst();
} else { // } else {
return Optional.empty(); // return Optional.empty();
} // }
} // }
public Optional<TaskletContext> getNextTasklet() { // public Optional<TaskletContext> getNextTasklet() {
return tasklets.stream() // return tasklets.stream()
.filter(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()).findFirst(); // .filter(t -> !t.getCurrentJob().isPresent() && t.checkExecutionTime()).findFirst();
} // }
@Override // @Override
public String toString() { // public String toString() {
return "something"; // return "something";
// return "(nJobs=" + segment.getNumberOfJobs() + ", nTasklets=" // // return "(nJobs=" + segment.getNumberOfJobs() + ", nTasklets="
// + segment.getNumberOfTasklets() + ", taskletWcet=" + segment.getTaskletWcet() + ")"; // // + segment.getNumberOfTasklets() + ", taskletWcet=" + segment.getTaskletWcet() + ")";
} // }
} // }
package mvd.jester.simulator.internals.dynamicforkjoin; // package mvd.jester.simulator.internals.dynamicforkjoin;
import java.util.ArrayList; // import java.util.ArrayList;
import java.util.Optional; // import java.util.Optional;
import mvd.jester.model.Segment; // import mvd.jester.model.Segment;
import mvd.jester.model.SynchronousTask; // import mvd.jester.model.SynchronousTask;
import mvd.jester.simulator.EventPrinter; // import mvd.jester.simulator.EventPrinter;
import mvd.jester.simulator.internals.JobContextInterface; // import mvd.jester.simulator.internals.ISubtaskContext;
import mvd.jester.simulator.internals.TaskContextInterface; // import mvd.jester.simulator.internals.ITaskContext;
/** // /**
* TaskContext // * TaskContext
*/ // */
public class TaskContext implements TaskContextInterface { // public class TaskContext implements ITaskContext {
private final SynchronousTask task; // private final SynchronousTask task;
private final ArrayList<SegmentContext> segments; // private final ArrayList<SegmentContext> segments;
private final long releaseTime; // private final long releaseTime;
private final long deadline; // private final long deadline;
private int currentSegment; // private int currentSegment;
private int segmentCounter; // private int segmentCounter;
public TaskContext(SynchronousTask task, long numberOfProcessors, long releaseTime) { // public TaskContext(SynchronousTask task, long numberOfProcessors, long releaseTime) {
this.task = task; // this.task = task;
this.segments = new ArrayList<>(); // this.segments = new ArrayList<>();
this.currentSegment = 0; // this.currentSegment = 0;
this.segmentCounter = 0; // this.segmentCounter = 0;
this.deadline = releaseTime + task.getDeadline(); // this.deadline = releaseTime + task.getDeadline();
this.releaseTime = releaseTime; // this.releaseTime = releaseTime;
for (Segment s : task.getWorkloadDistribution()) { // for (Segment s : task.getWorkloadDistribution()) {
segments.add(new SegmentContext(this, s, numberOfProcessors)); // segments.add(new SegmentContext(this, s, numberOfProcessors));
} // }
} // }
/** // /**
* @return the task // * @return the task
*/ // */
public SynchronousTask getTask() { // public SynchronousTask getTask() {
return task; // return task;
} // }
/** // /**
* @return the deadline // * @return the deadline
*/ // */
@Override // @Override
public long getDeadline() { // public long getDeadline() {
return deadline; // return deadline;
} // }
@Override // @Override
public long getReleaseTime() { // public long getReleaseTime() {
return releaseTime; // return releaseTime;
} // }
public Optional<TaskContextInterface> acceptNotification(long time) { // public Optional<ITaskContext> acceptNotification(long time) {
segmentCounter++; // segmentCounter++;
// if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfTasklets()) { // // if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfTasklets()) {
// currentSegment++; // // currentSegment++;
// segmentCounter = 0; // // segmentCounter = 0;
// if (currentSegment >= segments.size()) { // // if (currentSegment >= segments.size()) {
// EventPrinter.print("Time " + time + ": Task " + this + "finished!"); // // EventPrinter.print("Time " + time + ": Task " + this + "finished!");
// return Optional.of(this); // // return Optional.of(this);
// } // // }
// } // // }
return Optional.empty(); // return Optional.empty();
} // }
public Optional<JobContextInterface> getNextJob() { // public Optional<ISubtaskContext> getNextJob() {
if (currentSegment < segments.size()) { // if (currentSegment < segments.size()) {
return segments.get(currentSegment).getNextJob(); // return segments.get(currentSegment).getNextJob();
} // }
return Optional.empty(); // return Optional.empty();
} // }
@Override // @Override
public String toString() { // public String toString() {
return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments=" // return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments="
+ segments.size() + ")"; // + segments.size() + ")";
} // }
} // }
package mvd.jester.simulator.internals.dynamicforkjoin; // package mvd.jester.simulator.internals.dynamicforkjoin;
import java.util.Optional; // import java.util.Optional;
/** // /**
* Tasklet // * Tasklet
*/ // */
public class TaskletContext { // public class TaskletContext {
private final TaskContext taskContext; // private final TaskContext taskContext;
private Optional<JobContext> currentJob; // private Optional<JobContext> currentJob;
private final long wcet; // private final long wcet;
private long executionTime; // private long executionTime;
public TaskletContext(TaskContext taskContext, SegmentContext segment) { // public TaskletContext(TaskContext taskContext, SegmentContext segment) {
this.taskContext = taskContext; // this.taskContext = taskContext;
this.wcet = 88; // this.wcet = 88;
// segment.getSegment().getTaskletWcet(); // // segment.getSegment().getTaskletWcet();
this.executionTime = wcet; // this.executionTime = wcet;
currentJob = Optional.empty(); // currentJob = Optional.empty();
} // }
/** // /**
* @return the currentJob // * @return the currentJob
*/ // */
public Optional<JobContext> getCurrentJob() { // public Optional<JobContext> getCurrentJob() {
return currentJob; // return currentJob;
} // }
public void setCurrentJob(JobContext jobContext) { // public void setCurrentJob(JobContext jobContext) {
currentJob = Optional.ofNullable(jobContext); // currentJob = Optional.ofNullable(jobContext);
} // }
/** // /**
* @return true if tasklet finished, false otherwise // * @return true if tasklet finished, false otherwise
*/ // */
public boolean updateExecution(long time) { // public boolean updateExecution(long time) {
executionTime--; // executionTime--;
if (executionTime == 0) { // if (executionTime == 0) {
if (currentJob.isPresent()) { // if (currentJob.isPresent()) {
currentJob.get().setCurrentTasklet(null); // currentJob.get().setCurrentTasklet(null);
} // }
currentJob = Optional.empty(); // currentJob = Optional.empty();
return true; // return true;
} else if (executionTime < 0) { // } else if (executionTime < 0) {
throw new RuntimeException("Tasklet was executed for longer than its WCET!"); // throw new RuntimeException("Tasklet was executed for longer than its WCET!");
} // }
return false; // return false;
} // }
public boolean checkExecutionTime() { // public boolean checkExecutionTime() {
return executionTime > 0; // return executionTime > 0;
} // }
@Override // @Override
public String toString() { // public String toString() {
return "(wcet=" + wcet + ", task=" + taskContext + ")"; // return "(wcet=" + wcet + ", task=" + taskContext + ")";
} // }
} // }
package mvd.jester.simulator.internals.parallelsynchronous; // package mvd.jester.simulator.internals.parallelsynchronous;
import java.util.Optional; // import java.util.Optional;
import mvd.jester.simulator.EventPrinter; // import mvd.jester.simulator.EventPrinter;
import mvd.jester.simulator.internals.JobContextInterface; // import mvd.jester.simulator.internals.ISubtaskContext;
import mvd.jester.simulator.internals.ProcessorContext; // import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.TaskContextInterface; // import mvd.jester.simulator.internals.ITaskContext;
/** // /**
* Job // * Job
* // *
* @param <Job> // * @param <Job>
*/ // */
public class JobContext implements JobContextInterface { // public class JobContext implements ISubtaskContext {
private final TaskContext taskContext; // private final TaskContext taskContext;
private final SegmentContext segmentContext; // private final SegmentContext segmentContext;
private final long wcet; // private final long wcet;
private Optional<ProcessorContext> currentProcessor; // private Optional<ProcessorContext> currentProcessor;
private long executionTime; // private long executionTime;
public JobContext(TaskContext taskContext, SegmentContext segmentContext) { // public JobContext(TaskContext taskContext, SegmentContext segmentContext) {
this.currentProcessor = Optional.empty(); // this.currentProcessor = Optional.empty();
this.taskContext = taskContext; // this.taskContext = taskContext;
this.segmentContext = segmentContext; // this.segmentContext = segmentContext;
this.wcet = segmentContext.getSegment().getJobWcet(); // this.wcet = segmentContext.getSegment().getJobWcet();
this.executionTime = wcet; // this.executionTime = wcet;
} // }
public Optional<TaskContextInterface> updateExecution(long time) { // public Optional<ITaskContext> updateExecution(long time) {
executionTime--; // executionTime--;
if (executionTime == 0) { // if (executionTime == 0) {
EventPrinter.print("Time " + time + ": " + currentProcessor.get() // EventPrinter.print("Time " + time + ": " + currentProcessor.get()
+ " finished execution of job " + this + "!"); // + " finished execution of job " + this + "!");
currentProcessor.get().setJob(null); // currentProcessor.get().setJob(null);
currentProcessor = Optional.empty(); // currentProcessor = Optional.empty();
return taskContext.acceptNotification(time); // return taskContext.acceptNotification(time);
} else if (executionTime < 0) { // } else if (executionTime < 0) {
throw new RuntimeException("Job was executed for longer than its WCET!"); // throw new RuntimeException("Job was executed for longer than its WCET!");
} // }
return Optional.empty(); // return Optional.empty();
} // }
public boolean checkExecutionTime() { // public boolean checkExecutionTime() {
return executionTime > 0; // return executionTime > 0;
} // }
/** // /**
* @return the wcet // * @return the wcet
*/ // */
public long getWcet() { // public long getWcet() {
return wcet; // return wcet;
} // }
/** // /**
* @param processor the currentProcessor to set // * @param processor the currentProcessor to set
*/ // */
public void setCurrentProcessor(ProcessorContext processor) { // public void setCurrentProcessor(ProcessorContext processor) {
this.currentProcessor = Optional.ofNullable(processor); // this.currentProcessor = Optional.ofNullable(processor);
} // }
/** // /**
* @return the currentProcessor // * @return the currentProcessor
*/ // */
public Optional<ProcessorContext> getCurrentProcessor() { // public Optional<ProcessorContext> getCurrentProcessor() {
return currentProcessor; // return currentProcessor;
} // }
/** // /**
* @return the segmentContext // * @return the segmentContext
*/ // */
public SegmentContext getSegmentContext() { // public SegmentContext getSegmentContext() {
return segmentContext; // return segmentContext;
} // }
/** // /**
* @return the taskContext // * @return the taskContext
*/ // */
public TaskContext getTaskContext() { // public TaskContext getTaskContext() {
return taskContext; // return taskContext;
} // }
@Override // @Override
public String toString() { // public String toString() {
return "(jobWcet=" + wcet + ", of task=" + taskContext + ")"; // return "(jobWcet=" + wcet + ", of task=" + taskContext + ")";
} // }
@Override // @Override
public boolean prepareJob(long time) { // public boolean prepareJob(long time) {
return true; // return true;
} // }
} // }
package mvd.jester.simulator.internals.parallelsynchronous; // package mvd.jester.simulator.internals.parallelsynchronous;
import java.util.HashSet; // import java.util.HashSet;
import java.util.Optional; // import java.util.Optional;
import java.util.Set; // import java.util.Set;
import mvd.jester.model.Segment; // import mvd.jester.model.Segment;
import mvd.jester.simulator.internals.JobContextInterface; // import mvd.jester.simulator.internals.ISubtaskContext;
/** // /**
* Segment // * Segment
*/ // */
public class SegmentContext { // public class SegmentContext {
private final Segment segment; // private final Segment segment;
private final Set<JobContextInterface> jobs; // private final Set<ISubtaskContext> jobs;
public SegmentContext(TaskContext taskContext, Segment segment) { // public SegmentContext(TaskContext taskContext, Segment segment) {
this.segment = segment; // this.segment = segment;
jobs = new HashSet<>(); // jobs = new HashSet<>();
for (int j = 0; j < segment.getNumberOfJobs(); ++j) { // for (int j = 0; j < segment.getNumberOfJobs(); ++j) {
jobs.add(new JobContext(taskContext, this)); // jobs.add(new JobContext(taskContext, this));
} // }
} // }
/** // /**
* @return the segment // * @return the segment
*/ // */
public Segment getSegment() { // public Segment getSegment() {
return segment; // return segment;
} // }
public Optional<JobContextInterface> getNextJob() { // public Optional<ISubtaskContext> getNextJob() {
return jobs.stream() // return jobs.stream()
.filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime()) // .filter(j -> !j.getCurrentProcessor().isPresent() && j.checkExecutionTime())
.findFirst(); // .findFirst();
} // }
@Override // @Override
public String toString() { // public String toString() {
return "(nJobs=" + segment.getNumberOfJobs() + ", jobWcet=" + segment.getJobWcet() + ")"; // return "(nJobs=" + segment.getNumberOfJobs() + ", jobWcet=" + segment.getJobWcet() + ")";
} // }
} // }
package mvd.jester.simulator.internals.parallelsynchronous; // package mvd.jester.simulator.internals.parallelsynchronous;
import java.util.ArrayList; // import java.util.ArrayList;
import java.util.Optional; // import java.util.Optional;
import mvd.jester.model.Segment; // import mvd.jester.model.Segment;
import mvd.jester.model.SynchronousTask; // import mvd.jester.model.SynchronousTask;
import mvd.jester.simulator.EventPrinter; // import mvd.jester.simulator.EventPrinter;
import mvd.jester.simulator.internals.JobContextInterface; // import mvd.jester.simulator.internals.ISubtaskContext;
import mvd.jester.simulator.internals.TaskContextInterface; // import mvd.jester.simulator.internals.ITaskContext;
/** // /**
* TaskContext // * TaskContext
*/ // */
public class TaskContext implements TaskContextInterface { // public class TaskContext implements ITaskContext {
private final SynchronousTask task; // private final SynchronousTask task;
private final ArrayList<SegmentContext> segments; // private final ArrayList<SegmentContext> segments;
private final long deadline; // private final long deadline;
private final long releaseTime; // private final long releaseTime;
private int currentSegment; // private int currentSegment;
private int segmentCounter; // private int segmentCounter;
public TaskContext(SynchronousTask task, long releaseTime) { // public TaskContext(SynchronousTask task, long releaseTime) {
this.task = task; // this.task = task;
this.segments = new ArrayList<>(); // this.segments = new ArrayList<>();
this.currentSegment = 0; // this.currentSegment = 0;
this.segmentCounter = 0; // this.segmentCounter = 0;
this.releaseTime = releaseTime; // this.releaseTime = releaseTime;
this.deadline = releaseTime + task.getDeadline(); // this.deadline = releaseTime + task.getDeadline();
for (Segment s : task.getWorkloadDistribution()) { // for (Segment s : task.getWorkloadDistribution()) {
segments.add(new SegmentContext(this, s)); // segments.add(new SegmentContext(this, s));
} // }
} // }
/** // /**
* @return the task // * @return the task
*/ // */
public SynchronousTask getTask() { // public SynchronousTask getTask() {
return task; // return task;
} // }
/** // /**
* @return the deadline // * @return the deadline
*/ // */
@Override // @Override
public long getDeadline() { // public long getDeadline() {
return deadline; // return deadline;
} // }
@Override // @Override
public long getReleaseTime() { // public long getReleaseTime() {
return releaseTime; // return releaseTime;
} // }
public Optional<TaskContextInterface> acceptNotification(long time) { // public Optional<ITaskContext> acceptNotification(long time) {
segmentCounter++; // segmentCounter++;
if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfJobs()) { // if (segmentCounter >= segments.get(currentSegment).getSegment().getNumberOfJobs()) {
currentSegment++; // currentSegment++;
segmentCounter = 0; // segmentCounter = 0;
if (currentSegment >= segments.size()) { // if (currentSegment >= segments.size()) {
EventPrinter.print("Time " + time + ": Task " + this + "finished!"); // EventPrinter.print("Time " + time + ": Task " + this + "finished!");
return Optional.of(this); // return Optional.of(this);
} // }
} // }
return Optional.empty(); // return Optional.empty();
} // }
public Optional<JobContextInterface> getNextJob() { // public Optional<ISubtaskContext> getNextJob() {
if (currentSegment < segments.size()) { // if (currentSegment < segments.size()) {
return segments.get(currentSegment).getNextJob(); // return segments.get(currentSegment).getNextJob();
} // }
return Optional.empty(); // return Optional.empty();
} // }
@Override // @Override
public String toString() { // public String toString() {
return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments=" // return "(period=" + task.getPeriod() + ", deadline=" + deadline + ", segments="
+ segments.size() + ")"; // + segments.size() + ")";
} // }
} // }
package mvd.jester.simulator.model;
import mvd.jester.model.Subtask;
import mvd.jester.model.SubtaskContext;
public class ExtendedSubtaskContext extends SubtaskContext {
private JobContext jobContext;
public ExtendedSubtaskContext(JobContext jobContext, Subtask subtask) {
super(subtask);
this.jobContext = jobContext;
}
public JobContext getJobContext() {
return jobContext;
}
}
package mvd.jester.simulator.model;
import mvd.jester.model.Task;
/**
* JobContextInterface
*/
public interface ISubtaskContext {
public void updateWcet(long time);
public Task getTask();
}
package mvd.jester.simulator.internals; package mvd.jester.simulator.model;
import java.util.Optional; import java.util.Optional;
import mvd.jester.model.SynchronousTask; import mvd.jester.model.Task;
/** /**
* TaskContextInterface * TaskContextInterface
*/ */
public interface TaskContextInterface { public interface ITaskContext {
public SynchronousTask getTask(); public Task getTask();
public Optional<TaskContextInterface> acceptNotification(long time); public Optional<ITaskContext> acceptNotification(long time);
public Optional<JobContextInterface> getNextJob(); public Optional<ISubtaskContext> getNextJob();
public boolean checkRemainingThreads();
public long getDeadline(); public long getDeadline();
......
package mvd.jester.simulator.model;
import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
import org.jgrapht.graph.DefaultEdge;
import mvd.jester.model.DagTask;
import mvd.jester.model.Subtask;
public class JobContext {
private final DagTask task;
private final long releaseTime;
private final long deadline;
private final Subtask source;
// private long activeThreads; // TODO: Use threads
public JobContext(DagTask task, long releaseTime) {
this.task = task;
this.releaseTime = releaseTime;
this.deadline = releaseTime + task.getDeadline();
this.source = findSource(task);
// this.activeThreads = task.getNumberOfThreads();
}
private Subtask findSource(DagTask task) {
DirectedAcyclicGraph<Subtask, DefaultEdge> jobDag = task.getJobDag();
for (Subtask subtask : jobDag) {
if (jobDag.inDegreeOf(subtask) == 0) {
return subtask;
}
}
throw new RuntimeException("No source found in DAG. How can that be!?");
}
/**
* @return the task
*/
public DagTask getTask() {
return task;
}
/**
* @return the source
*/
public Subtask getSource() {
return source;
}
/**
* @return the deadline
*/
public long getDeadline() {
return deadline;
}
/**
* @return the releaseTime
*/
public long getReleaseTime() {
return releaseTime;
}
public boolean checkRemainingThreads() {
return false;
}
}
package mvd.jester.simulator.model;
import java.util.Optional;
import mvd.jester.priority.PriorityManager;
import mvd.jester.simulator.exceptions.DeadlineMissedException;
import mvd.jester.simulator.exceptions.ExecutionOverrunException;
/**
* Processor
*/
public class ProcessorContext {
private final long processorId;
private Optional<ExtendedSubtaskContext> currentSubtask;
private long lastEventTime;
public ProcessorContext(long processorId) {
currentSubtask = Optional.empty();
this.processorId = processorId;
this.lastEventTime = 0;
}
public void setSubtask(ExtendedSubtaskContext subtask) {
this.currentSubtask = Optional.ofNullable(subtask);
}
public boolean accept(ExtendedSubtaskContext context, long time) {
if (isIdle()) {
this.currentSubtask = Optional.of(context);
lastEventTime = time;
return true;
}
return false;
}
/**
* @return the currentJob
*/
public Optional<ExtendedSubtaskContext> getSubtask() {
return currentSubtask;
}
public boolean canAccept(ExtendedSubtaskContext subtaskContext,
PriorityManager priorityManager) {
if (subtaskContext == null) {
return false;
}
if (currentSubtask.isEmpty()) {
if (subtaskContext.getJobContext().checkRemainingThreads()) {
return true;
}
return false;
}
if (priorityManager.compare(subtaskContext.getJobContext(),
currentSubtask.get().getJobContext()) < 0) {
return true;
}
return false;
}
public void free() {
currentSubtask = Optional.ofNullable(null);
}
public boolean isIdle() {
if (currentSubtask.isEmpty()) {
return true;
}
return false;
}
public void update(long time) {
if (currentSubtask.isPresent()) {
currentSubtask.get().updateRemainingExecutionTime(time - lastEventTime);
lastEventTime = time;
long remainingTime = currentSubtask.get().getRemainingExecutionTime();
if (remainingTime < 0) {
throw new ExecutionOverrunException(currentSubtask.get().getJobContext()
+ " overruns its execution at time " + time + ": " + remainingTime);
}
if (time > currentSubtask.get().getJobContext().getDeadline()) {
throw new DeadlineMissedException(
currentSubtask.get().getJobContext() + " misses its deadline");
}
}
}
@Override
public String toString() {
return "Processor " + processorId;
}
}
...@@ -68,7 +68,8 @@ public class FonsecaNelis extends AbstractTest<DagTask> { ...@@ -68,7 +68,8 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
final DirectedAcyclicGraph<Subtask, DefaultEdge> nfjJobDag = final DirectedAcyclicGraph<Subtask, DefaultEdge> nfjJobDag =
DagUtils.createNFJGraph(jobDag); DagUtils.createNFJGraph(jobDag);
final BinaryDecompositionTree<Subtask> tree = DagUtils.createDecompositionTree(nfjJobDag); final BinaryDecompositionTree<Subtask> tree =
DagUtils.createDecompositionTree(nfjJobDag);
carryOutSegments.put(t, constructCarryOutDistribution(nfjJobDag, tree)); carryOutSegments.put(t, constructCarryOutDistribution(nfjJobDag, tree));
} }
...@@ -83,14 +84,15 @@ public class FonsecaNelis extends AbstractTest<DagTask> { ...@@ -83,14 +84,15 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
boolean isEmpty = false; boolean isEmpty = false;
do { do {
final Set<SubtaskContext> parallelJobs = getMaximumParallelism(modifiedTree.getRootNode()); final Set<SubtaskContext> parallelJobs =
final Optional<SubtaskContext> min = getMaximumParallelism(modifiedTree.getRootNode());
parallelJobs.stream().min((p1, p2) -> Long.compare(p1.getWcet(), p2.getWcet())); final Optional<SubtaskContext> min = parallelJobs.stream().min((p1, p2) -> Long
.compare(p1.getRemainingExecutionTime(), p2.getRemainingExecutionTime()));
if (min.isPresent()) { if (min.isPresent()) {
final long width = min.get().getWcet(); final long width = min.get().getRemainingExecutionTime();
carryOutWorkload.add(new Segment(width, parallelJobs.size())); carryOutWorkload.add(new Segment(width, parallelJobs.size()));
for (final SubtaskContext p : parallelJobs) { for (final SubtaskContext p : parallelJobs) {
p.setWcet(p.getWcet() - width); p.setRemainingExecutionTime(p.getRemainingExecutionTime() - width);
} }
} else { } else {
break; break;
...@@ -104,17 +106,20 @@ public class FonsecaNelis extends AbstractTest<DagTask> { ...@@ -104,17 +106,20 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
private BinaryDecompositionTree<SubtaskContext> transformTree( private BinaryDecompositionTree<SubtaskContext> transformTree(
final BinaryDecompositionTree<Subtask> tree) { final BinaryDecompositionTree<Subtask> tree) {
final BinaryDecompositionTree<SubtaskContext> modifiedTree = new BinaryDecompositionTree<>(); final BinaryDecompositionTree<SubtaskContext> modifiedTree =
new BinaryDecompositionTree<>();
final Node<SubtaskContext> root = transformNode(null, tree.getRootNode()); final Node<SubtaskContext> root = transformNode(null, tree.getRootNode());
modifiedTree.setRoot(root); modifiedTree.setRoot(root);
return modifiedTree; return modifiedTree;
} }
private Node<SubtaskContext> transformNode(final Node<SubtaskContext> parent, final Node<Subtask> node) { private Node<SubtaskContext> transformNode(final Node<SubtaskContext> parent,
final Node<Subtask> node) {
if (node.getNodeType().equals(NodeType.LEAF)) { if (node.getNodeType().equals(NodeType.LEAF)) {
return new Node<SubtaskContext>(parent, new SubtaskContext(node.getObject())); return new Node<SubtaskContext>(parent, new SubtaskContext(node.getObject()));
} else { } else {
final Node<SubtaskContext> modifiedNode = new Node<SubtaskContext>(parent, node.getNodeType()); final Node<SubtaskContext> modifiedNode =
new Node<SubtaskContext>(parent, node.getNodeType());
modifiedNode.setLeftNode(transformNode(modifiedNode, node.getLeftNode())); modifiedNode.setLeftNode(transformNode(modifiedNode, node.getLeftNode()));
modifiedNode.setRightNode(transformNode(modifiedNode, node.getRightNode())); modifiedNode.setRightNode(transformNode(modifiedNode, node.getRightNode()));
return modifiedNode; return modifiedNode;
...@@ -136,7 +141,7 @@ public class FonsecaNelis extends AbstractTest<DagTask> { ...@@ -136,7 +141,7 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
return right; return right;
} }
} else { } else {
if (node.getObject().getWcet() > 0) { if (node.getObject().getRemainingExecutionTime() > 0) {
return new HashSet<>(Arrays.asList(node.getObject())); return new HashSet<>(Arrays.asList(node.getObject()));
} else { } else {
return new HashSet<>(); return new HashSet<>();
......
package mvd.jester.priority; // package mvd.jester.priority;
import static org.junit.jupiter.api.Assertions.assertFalse; // import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; // import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock; // import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; // import static org.mockito.Mockito.when;
import org.junit.jupiter.api.DisplayName; // import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; // import org.junit.jupiter.api.Test;
import mvd.jester.model.SynchronousTask; // import mvd.jester.model.SynchronousTask;
import mvd.jester.model.SystemManager; // import mvd.jester.model.SystemManager;
import mvd.jester.simulator.DynamicForkJoin; // import mvd.jester.simulator.DynamicForkJoin;
import mvd.jester.simulator.ParallelSynchronous; // import mvd.jester.simulator.ParallelSynchronous;
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext; // import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
import mvd.jester.tests.ChwaLee; // import mvd.jester.tests.ChwaLee;
import mvd.jester.tests.MaiaBertogna; // import mvd.jester.tests.MaiaBertogna;
import mvd.jester.tests.SchmidMottok; // import mvd.jester.tests.SchmidMottok;
import mvd.jester.tests.TypeFunction; // import mvd.jester.tests.TypeFunction;
/** // /**
* TestEarliestDeadlineFirst // * TestEarliestDeadlineFirst
*/ // */
public class TestEarliestDeadlineFirst { // public class TestEarliestDeadlineFirst {
@Test // @Test
@DisplayName("Test if priority manager returns the correct priority.") // @DisplayName("Test if priority manager returns the correct priority.")
public void testPriority() { // public void testPriority() {
EarliestDeadlineFirst edf = new EarliestDeadlineFirst(); // EarliestDeadlineFirst edf = new EarliestDeadlineFirst();
SynchronousTask t1 = mock(SynchronousTask.class); // SynchronousTask t1 = mock(SynchronousTask.class);
SynchronousTask t2 = mock(SynchronousTask.class); // SynchronousTask t2 = mock(SynchronousTask.class);
when(t1.getDeadline()).thenReturn((long) 100); // when(t1.getDeadline()).thenReturn((long) 100);
when(t2.getDeadline()).thenReturn((long) 200); // when(t2.getDeadline()).thenReturn((long) 200);
TaskContext tc1 = mock(TaskContext.class); // TaskContext tc1 = mock(TaskContext.class);
TaskContext tc2 = mock(TaskContext.class); // TaskContext tc2 = mock(TaskContext.class);
when(tc1.getDeadline()).thenReturn((long) 100); // when(tc1.getDeadline()).thenReturn((long) 100);
when(tc2.getDeadline()).thenReturn((long) 200); // when(tc2.getDeadline()).thenReturn((long) 200);
assertTrue(edf.compare(t1, t2) < 0); // assertTrue(edf.compare(t1, t2) < 0);
assertTrue(edf.compare(tc1, tc2) < 0); // assertTrue(edf.compare(tc1, tc2) < 0);
assertTrue(edf.compare(t1, t1) == 0); // assertTrue(edf.compare(t1, t1) == 0);
assertTrue(edf.compare(tc1, tc1) == 0); // assertTrue(edf.compare(tc1, tc1) == 0);
assertTrue(edf.compare(t2, t1) > 0); // assertTrue(edf.compare(t2, t1) > 0);
assertTrue(edf.compare(tc2, tc1) > 0); // assertTrue(edf.compare(tc2, tc1) > 0);
} // }
@Test // @Test
@DisplayName("Check Getters, Tests and Simulators.") // @DisplayName("Check Getters, Tests and Simulators.")
void testGettersTestsAndSimulators() { // void testGettersTestsAndSimulators() {
EarliestDeadlineFirst edf = new EarliestDeadlineFirst(); // EarliestDeadlineFirst edf = new EarliestDeadlineFirst();
SystemManager manager = new SystemManager(4); // SystemManager manager = new SystemManager(4);
assertTrue(edf.hasTest(ChwaLee.class)); // assertTrue(edf.hasTest(ChwaLee.class));
assertFalse(edf.hasTest(MaiaBertogna.class)); // assertFalse(edf.hasTest(MaiaBertogna.class));
assertFalse(edf.hasTest(SchmidMottok.class)); // assertFalse(edf.hasTest(SchmidMottok.class));
assertTrue(edf.hasSimulator(ParallelSynchronous.class)); // assertTrue(edf.hasSimulator(ParallelSynchronous.class));
assertTrue(edf.hasSimulator(DynamicForkJoin.class)); // assertTrue(edf.hasSimulator(DynamicForkJoin.class));
assertTrue(edf.hasTest(new ChwaLee(manager))); // assertTrue(edf.hasTest(new ChwaLee(manager)));
assertFalse(edf.hasTest(new SchmidMottok(new TypeFunction.KownStructure(), manager))); // assertFalse(edf.hasTest(new SchmidMottok(new TypeFunction.KownStructure(), manager)));
assertFalse(edf.hasTest(new MaiaBertogna(manager))); // assertFalse(edf.hasTest(new MaiaBertogna(manager)));
// assertTrue(edf.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class)))); // // assertTrue(edf.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class))));
// assertTrue(edf.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class)))); // // assertTrue(edf.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class))));
assertTrue(edf.getName().equals("EDF")); // assertTrue(edf.getName().equals("EDF"));
} // }
} // }
package mvd.jester.priority; // package mvd.jester.priority;
import static org.junit.jupiter.api.Assertions.assertFalse; // import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; // import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock; // import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; // import static org.mockito.Mockito.when;
import org.junit.jupiter.api.DisplayName; // import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; // import org.junit.jupiter.api.Test;
import mvd.jester.model.SynchronousTask; // import mvd.jester.model.SynchronousTask;
import mvd.jester.model.SystemManager; // import mvd.jester.model.SystemManager;
import mvd.jester.simulator.DynamicForkJoin; // import mvd.jester.simulator.DynamicForkJoin;
import mvd.jester.simulator.ParallelSynchronous; // import mvd.jester.simulator.ParallelSynchronous;
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext; // import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
import mvd.jester.tests.ChwaLee; // import mvd.jester.tests.ChwaLee;
import mvd.jester.tests.MaiaBertogna; // import mvd.jester.tests.MaiaBertogna;
import mvd.jester.tests.SchmidMottok; // import mvd.jester.tests.SchmidMottok;
import mvd.jester.tests.TypeFunction; // import mvd.jester.tests.TypeFunction;
/** // /**
* TestRateMonotonic // * TestRateMonotonic
*/ // */
public class TestRateMonotonic { // public class TestRateMonotonic {
@Test // @Test
@DisplayName("Test if priority manager returns the correct priority.") // @DisplayName("Test if priority manager returns the correct priority.")
public void testPriority() { // public void testPriority() {
RateMonotonic rm = new RateMonotonic(); // RateMonotonic rm = new RateMonotonic();
SynchronousTask t1 = mock(SynchronousTask.class); // SynchronousTask t1 = mock(SynchronousTask.class);
SynchronousTask t2 = mock(SynchronousTask.class); // SynchronousTask t2 = mock(SynchronousTask.class);
when(t1.getPeriod()).thenReturn((long) 100); // when(t1.getPeriod()).thenReturn((long) 100);
when(t2.getPeriod()).thenReturn((long) 200); // when(t2.getPeriod()).thenReturn((long) 200);
TaskContext tc1 = mock(TaskContext.class); // TaskContext tc1 = mock(TaskContext.class);
TaskContext tc2 = mock(TaskContext.class); // TaskContext tc2 = mock(TaskContext.class);
when(tc1.getTask()).thenReturn(t1); // when(tc1.getTask()).thenReturn(t1);
when(tc2.getTask()).thenReturn(t2); // when(tc2.getTask()).thenReturn(t2);
assertTrue(rm.compare(t1, t2) < 0); // assertTrue(rm.compare(t1, t2) < 0);
assertTrue(rm.compare(tc1, tc2) < 0); // assertTrue(rm.compare(tc1, tc2) < 0);
assertTrue(rm.compare(t1, t1) == 0); // assertTrue(rm.compare(t1, t1) == 0);
assertTrue(rm.compare(tc1, tc1) == 0); // assertTrue(rm.compare(tc1, tc1) == 0);
assertTrue(rm.compare(t2, t1) > 0); // assertTrue(rm.compare(t2, t1) > 0);
assertTrue(rm.compare(tc2, tc1) > 0); // assertTrue(rm.compare(tc2, tc1) > 0);
} // }
@Test // @Test
@DisplayName("Check Tests and Simulators.") // @DisplayName("Check Tests and Simulators.")
void testTestsAndSimulators() { // void testTestsAndSimulators() {
RateMonotonic rm = new RateMonotonic(); // RateMonotonic rm = new RateMonotonic();
SystemManager manager = new SystemManager(8); // SystemManager manager = new SystemManager(8);
assertFalse(rm.hasTest(ChwaLee.class)); // assertFalse(rm.hasTest(ChwaLee.class));
assertTrue(rm.hasTest(MaiaBertogna.class)); // assertTrue(rm.hasTest(MaiaBertogna.class));
assertTrue(rm.hasTest(SchmidMottok.class)); // assertTrue(rm.hasTest(SchmidMottok.class));
assertTrue(rm.hasSimulator(ParallelSynchronous.class)); // assertTrue(rm.hasSimulator(ParallelSynchronous.class));
assertTrue(rm.hasSimulator(DynamicForkJoin.class)); // assertTrue(rm.hasSimulator(DynamicForkJoin.class));
assertFalse(rm.hasTest(new ChwaLee(manager))); // assertFalse(rm.hasTest(new ChwaLee(manager)));
assertTrue(rm.hasTest(new SchmidMottok(new TypeFunction.UnkownStructure(), manager))); // assertTrue(rm.hasTest(new SchmidMottok(new TypeFunction.UnkownStructure(), manager)));
assertTrue(rm.hasTest(new MaiaBertogna(manager))); // assertTrue(rm.hasTest(new MaiaBertogna(manager)));
// assertTrue(rm.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class)))); // // assertTrue(rm.hasSimulator(new ParallelSynchronous(mock(SystemSetup.class))));
// assertTrue(rm.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class)))); // // assertTrue(rm.hasSimulator(new DynamicForkJoin(mock(SystemSetup.class))));
assertTrue(rm.getName().equals("RM")); // assertTrue(rm.getName().equals("RM"));
} // }
} // }
package mvd.jester.simulator; // package mvd.jester.simulator;
import static org.junit.jupiter.api.Assertions.assertFalse; // import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows; // 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 static org.mockito.ArgumentMatchers.anyLong; // import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock; // import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; // import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; // import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; // import static org.mockito.Mockito.when;
import static org.mockito.AdditionalMatchers.gt; // import static org.mockito.AdditionalMatchers.gt;
import static org.mockito.AdditionalMatchers.lt; // import static org.mockito.AdditionalMatchers.lt;
import java.util.Optional; // import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom; // import java.util.concurrent.ThreadLocalRandom;
import org.junit.jupiter.api.DisplayName; // import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; // import org.junit.jupiter.api.Test;
import mvd.jester.model.SynchronousTask; // import mvd.jester.model.SynchronousTask;
import mvd.jester.simulator.internals.ProcessorContext; // import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.TaskContextInterface; // import mvd.jester.simulator.internals.ITaskContext;
import mvd.jester.simulator.internals.parallelsynchronous.JobContext; // import mvd.jester.simulator.internals.parallelsynchronous.JobContext;
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext; // import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
/** // /**
* TestProcessorContext // * TestProcessorContext
*/ // */
public class TestProcessorContext { // public class TestProcessorContext {
@Test // @Test
@DisplayName("Check if the job execution is updated correctly.") // @DisplayName("Check if the job execution is updated correctly.")
void testUpdateExecution() { // void testUpdateExecution() {
for (int run = 0; run < 100; ++run) { // for (int run = 0; run < 100; ++run) {
long jobWcet = ThreadLocalRandom.current().nextLong(1, 10); // long jobWcet = ThreadLocalRandom.current().nextLong(1, 10);
TaskContext task = mock(TaskContext.class); // TaskContext task = mock(TaskContext.class);
JobContext job = mock(JobContext.class); // JobContext job = mock(JobContext.class);
when(job.updateExecution(lt(jobWcet))).thenReturn(Optional.empty()); // when(job.updateExecution(lt(jobWcet))).thenReturn(Optional.empty());
when(job.updateExecution(jobWcet)).thenReturn(Optional.of(task)); // when(job.updateExecution(jobWcet)).thenReturn(Optional.of(task));
when(job.updateExecution(gt(jobWcet))).thenThrow(RuntimeException.class); // when(job.updateExecution(gt(jobWcet))).thenThrow(RuntimeException.class);
ProcessorContext processor = new ProcessorContext(1); // ProcessorContext processor = new ProcessorContext(1);
assertFalse(processor.updateExecution(0).isPresent()); // assertFalse(processor.updateExecution(0).isPresent());
processor.setJob(job); // processor.setJob(job);
for (int i = 0; i < jobWcet; ++i) { // for (int i = 0; i < jobWcet; ++i) {
assertFalse(processor.updateExecution(i).isPresent()); // assertFalse(processor.updateExecution(i).isPresent());
} // }
Optional<TaskContextInterface> tci = processor.updateExecution(jobWcet); // Optional<ITaskContext> tci = processor.updateExecution(jobWcet);
assertTrue(tci.isPresent()); // assertTrue(tci.isPresent());
assertTrue(tci.get().equals(task)); // assertTrue(tci.get().equals(task));
assertThrows(RuntimeException.class, () -> processor.updateExecution(jobWcet + 1)); // assertThrows(RuntimeException.class, () -> processor.updateExecution(jobWcet + 1));
verify(job, times((int) jobWcet + 2)).updateExecution(anyLong()); // verify(job, times((int) jobWcet + 2)).updateExecution(anyLong());
} // }
} // }
@Test // @Test
@DisplayName("Check if the processor correctly accepts jobs") // @DisplayName("Check if the processor correctly accepts jobs")
void testAcceptTask() { // void testAcceptTask() {
for (int run = 0; run < 100; ++run) { // for (int run = 0; run < 100; ++run) {
long firstPeriod = ThreadLocalRandom.current().nextLong(100, 1000); // long firstPeriod = ThreadLocalRandom.current().nextLong(100, 1000);
long secondPeriod = ThreadLocalRandom.current().nextLong(100, 1000); // long secondPeriod = ThreadLocalRandom.current().nextLong(100, 1000);
JobContext firstJob = mock(JobContext.class); // JobContext firstJob = mock(JobContext.class);
TaskContext firstTaskContext = mock(TaskContext.class); // TaskContext firstTaskContext = mock(TaskContext.class);
SynchronousTask firstTask = mock(SynchronousTask.class); // SynchronousTask firstTask = mock(SynchronousTask.class);
when(firstJob.getTaskContext()).thenReturn(firstTaskContext); // when(firstJob.getJobContext()).thenReturn(firstTaskContext);
when(firstJob.prepareJob(anyLong())).thenReturn(true); // when(firstJob.prepareJob(anyLong())).thenReturn(true);
when(firstTaskContext.getTask()).thenReturn(firstTask); // when(firstTaskContext.getTask()).thenReturn(firstTask);
when(firstTaskContext.getNextJob()).thenReturn(Optional.of(firstJob)); // when(firstTaskContext.getNextJob()).thenReturn(Optional.of(firstJob));
when(firstTask.getPeriod()).thenReturn((long) firstPeriod); // when(firstTask.getPeriod()).thenReturn((long) firstPeriod);
JobContext secondJob = mock(JobContext.class); // JobContext secondJob = mock(JobContext.class);
TaskContext secondTaskContext = mock(TaskContext.class); // TaskContext secondTaskContext = mock(TaskContext.class);
SynchronousTask secondTask = mock(SynchronousTask.class); // SynchronousTask secondTask = mock(SynchronousTask.class);
when(secondJob.getTaskContext()).thenReturn(secondTaskContext); // when(secondJob.getJobContext()).thenReturn(secondTaskContext);
when(secondJob.prepareJob(anyLong())).thenReturn(true); // when(secondJob.prepareJob(anyLong())).thenReturn(true);
when(secondTaskContext.getTask()).thenReturn(secondTask); // when(secondTaskContext.getTask()).thenReturn(secondTask);
when(secondTaskContext.getNextJob()).thenReturn(Optional.of(secondJob)); // when(secondTaskContext.getNextJob()).thenReturn(Optional.of(secondJob));
when(secondTask.getPeriod()).thenReturn((long) secondPeriod); // when(secondTask.getPeriod()).thenReturn((long) secondPeriod);
ProcessorContext processor = new ProcessorContext(1); // ProcessorContext processor = new ProcessorContext(1);
assertTrue(processor.acceptTask(secondTaskContext, run)); // assertTrue(processor.acceptTask(secondTaskContext, run));
if (firstPeriod < secondPeriod) { // if (firstPeriod < secondPeriod) {
assertTrue(processor.acceptTask(firstTaskContext, run)); // assertTrue(processor.acceptTask(firstTaskContext, run));
} else { // } else {
assertFalse(processor.acceptTask(firstTaskContext, run)); // assertFalse(processor.acceptTask(firstTaskContext, run));
} // }
assertFalse(processor.acceptTask(secondTaskContext, run)); // assertFalse(processor.acceptTask(secondTaskContext, run));
int time = firstPeriod < secondPeriod ? 1 : 0; // int time = firstPeriod < secondPeriod ? 1 : 0;
verify(firstJob, times(time)).prepareJob(anyLong()); // verify(firstJob, times(time)).prepareJob(anyLong());
verify(firstJob, times(time)).setCurrentProcessor(processor); // verify(firstJob, times(time)).setCurrentProcessor(processor);
verify(firstTaskContext, times(time)).getNextJob(); // verify(firstTaskContext, times(time)).getNextJob();
verify(secondJob, times(1)).prepareJob(anyLong()); // verify(secondJob, times(1)).prepareJob(anyLong());
verify(secondJob, times(1)).setCurrentProcessor(processor); // verify(secondJob, times(1)).setCurrentProcessor(processor);
verify(secondJob, times(time)).setCurrentProcessor(null); // verify(secondJob, times(time)).setCurrentProcessor(null);
verify(secondTaskContext, times(1)).getNextJob(); // verify(secondTaskContext, times(1)).getNextJob();
} // }
} // }
} // }
package mvd.jester.simulator.dynamicforkjoin; // package mvd.jester.simulator.dynamicforkjoin;
import static org.junit.jupiter.api.Assertions.assertFalse; // import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; // import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyLong; // import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq; // import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.AdditionalMatchers.not; // import static org.mockito.AdditionalMatchers.not;
import static org.mockito.Mockito.mock; // import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; // import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; // import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; // import static org.mockito.Mockito.when;
import java.util.Optional; // import java.util.Optional;
import org.junit.jupiter.api.DisplayName; // import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; // import org.junit.jupiter.api.Test;
import mvd.jester.model.Segment; // import mvd.jester.model.Segment;
import mvd.jester.simulator.internals.ProcessorContext; // import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.dynamicforkjoin.JobContext; // import mvd.jester.simulator.internals.dynamicforkjoin.JobContext;
import mvd.jester.simulator.internals.dynamicforkjoin.SegmentContext; // import mvd.jester.simulator.internals.dynamicforkjoin.SegmentContext;
import mvd.jester.simulator.internals.dynamicforkjoin.TaskContext; // import mvd.jester.simulator.internals.dynamicforkjoin.TaskContext;
import mvd.jester.simulator.internals.dynamicforkjoin.TaskletContext;; // import mvd.jester.simulator.internals.dynamicforkjoin.TaskletContext;;
/** // /**
* TestJobContext // * TestJobContext
*/ // */
public class TestJobContext { // public class TestJobContext {
@Test // @Test
@DisplayName("Check if the job is prepared correctly.") // @DisplayName("Check if the job is prepared correctly.")
public void testPrepareJob() { // public void testPrepareJob() {
TaskContext tc = mock(TaskContext.class); // TaskContext tc = mock(TaskContext.class);
TaskletContext tlc = mock(TaskletContext.class); // TaskletContext tlc = mock(TaskletContext.class);
SegmentContext sc = mock(SegmentContext.class); // SegmentContext sc = mock(SegmentContext.class);
Segment s = mock(Segment.class); // Segment s = mock(Segment.class);
when(sc.getSegment()).thenReturn(s); // when(sc.getSegment()).thenReturn(s);
when(s.getJobWcet()).thenReturn((long) 20); // when(s.getJobWcet()).thenReturn((long) 20);
when(sc.getNextTasklet()).thenReturn(Optional.of(tlc)) // when(sc.getNextTasklet()).thenReturn(Optional.of(tlc))
.thenReturn(Optional.ofNullable(null)); // .thenReturn(Optional.ofNullable(null));
JobContext jc = new JobContext(tc, sc); // JobContext jc = new JobContext(tc, sc);
assertTrue(jc.prepareJob(0)); // assertTrue(jc.prepareJob(0));
assertTrue(jc.prepareJob(1)); // assertTrue(jc.prepareJob(1));
jc.setCurrentTasklet(null); // jc.setCurrentTasklet(null);
assertFalse(jc.prepareJob(2)); // assertFalse(jc.prepareJob(2));
} // }
@Test // @Test
@DisplayName("Check if the execution time is checked correctly.") // @DisplayName("Check if the execution time is checked correctly.")
void testCheckExecutionTime() { // void testCheckExecutionTime() {
TaskContext tc = mock(TaskContext.class); // TaskContext tc = mock(TaskContext.class);
TaskletContext tlc = mock(TaskletContext.class); // TaskletContext tlc = mock(TaskletContext.class);
SegmentContext sc = mock(SegmentContext.class); // SegmentContext sc = mock(SegmentContext.class);
Segment s = mock(Segment.class); // Segment s = mock(Segment.class);
when(sc.getSegment()).thenReturn(s); // when(sc.getSegment()).thenReturn(s);
when(s.getJobWcet()).thenReturn((long) 20); // when(s.getJobWcet()).thenReturn((long) 20);
when(tlc.checkExecutionTime()).thenReturn(true, false); // when(tlc.checkExecutionTime()).thenReturn(true, false);
JobContext jc = new JobContext(tc, sc); // JobContext jc = new JobContext(tc, sc);
assertFalse(jc.checkExecutionTime()); // assertFalse(jc.checkExecutionTime());
jc.setCurrentTasklet(tlc); // jc.setCurrentTasklet(tlc);
assertTrue(jc.checkExecutionTime()); // assertTrue(jc.checkExecutionTime());
assertFalse(jc.checkExecutionTime()); // assertFalse(jc.checkExecutionTime());
} // }
@Test // @Test
@DisplayName("Check if the execution is updated correctly.") // @DisplayName("Check if the execution is updated correctly.")
void checkUpdateExecution() { // void checkUpdateExecution() {
TaskContext tc = mock(TaskContext.class); // TaskContext tc = mock(TaskContext.class);
TaskletContext tlc = mock(TaskletContext.class); // TaskletContext tlc = mock(TaskletContext.class);
SegmentContext sc = mock(SegmentContext.class); // SegmentContext sc = mock(SegmentContext.class);
Segment s = mock(Segment.class); // Segment s = mock(Segment.class);
ProcessorContext pc = mock(ProcessorContext.class); // ProcessorContext pc = mock(ProcessorContext.class);
when(sc.getSegment()).thenReturn(s); // when(sc.getSegment()).thenReturn(s);
when(sc.getNextTasklet()).thenReturn(Optional.ofNullable(tlc)) // when(sc.getNextTasklet()).thenReturn(Optional.ofNullable(tlc))
.thenReturn(Optional.ofNullable(null)); // .thenReturn(Optional.ofNullable(null));
when(s.getJobWcet()).thenReturn((long) 20); // when(s.getJobWcet()).thenReturn((long) 20);
when(tlc.checkExecutionTime()).thenReturn(true, false); // when(tlc.checkExecutionTime()).thenReturn(true, false);
when(tlc.updateExecution(not(eq(0)))).thenReturn(true); // when(tlc.updateExecution(not(eq(0)))).thenReturn(true);
when(tlc.updateExecution(0)).thenReturn(false); // when(tlc.updateExecution(0)).thenReturn(false);
when(tc.acceptNotification(not(eq(1)))).thenReturn(Optional.ofNullable(null)); // when(tc.acceptNotification(not(eq(1)))).thenReturn(Optional.ofNullable(null));
when(tc.acceptNotification(1)).thenReturn(Optional.ofNullable(tc)); // when(tc.acceptNotification(1)).thenReturn(Optional.ofNullable(tc));
JobContext jc = new JobContext(tc, sc); // JobContext jc = new JobContext(tc, sc);
jc.setCurrentProcessor(pc); // jc.setCurrentProcessor(pc);
assertFalse(jc.updateExecution(0).isPresent()); // assertFalse(jc.updateExecution(0).isPresent());
assertFalse(jc.updateExecution(0).isPresent()); // assertFalse(jc.updateExecution(0).isPresent());
jc.setCurrentTasklet(tlc); // jc.setCurrentTasklet(tlc);
assertTrue(jc.updateExecution(1).isPresent()); // assertTrue(jc.updateExecution(1).isPresent());
verify(tlc, times(2)).updateExecution(anyLong()); // verify(tlc, times(2)).updateExecution(anyLong());
verify(tc, times(2)).acceptNotification(anyLong()); // verify(tc, times(2)).acceptNotification(anyLong());
verify(sc, times(2)).getNextTasklet(); // verify(sc, times(2)).getNextTasklet();
} // }
} // }
package mvd.jester.simulator.parallelsynchronous; // package mvd.jester.simulator.parallelsynchronous;
import static org.junit.jupiter.api.Assertions.assertFalse; // import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows; // 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 static org.mockito.ArgumentMatchers.anyLong; // import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock; // import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; // import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; // import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; // import static org.mockito.Mockito.when;
import java.util.Optional; // import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom; // import java.util.concurrent.ThreadLocalRandom;
import org.junit.jupiter.api.DisplayName; // import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; // import org.junit.jupiter.api.Test;
import mvd.jester.model.Segment; // import mvd.jester.model.Segment;
import mvd.jester.simulator.internals.ProcessorContext; // import mvd.jester.simulator.internals.ProcessorContext;
import mvd.jester.simulator.internals.TaskContextInterface; // import mvd.jester.simulator.internals.ITaskContext;
import mvd.jester.simulator.internals.parallelsynchronous.JobContext; // import mvd.jester.simulator.internals.parallelsynchronous.JobContext;
import mvd.jester.simulator.internals.parallelsynchronous.SegmentContext; // import mvd.jester.simulator.internals.parallelsynchronous.SegmentContext;
import mvd.jester.simulator.internals.parallelsynchronous.TaskContext; // import mvd.jester.simulator.internals.parallelsynchronous.TaskContext;
/** // /**
* TestJobContext // * TestJobContext
*/ // */
public class TestJobContext { // public class TestJobContext {
@Test // @Test
@DisplayName("Check if execution of Job is updated correctly.") // @DisplayName("Check if execution of Job is updated correctly.")
public void testUpdateExecution() { // public void testUpdateExecution() {
for (int run = 0; run < 100; ++run) { // for (int run = 0; run < 100; ++run) {
long jobWcet = ThreadLocalRandom.current().nextLong(20, 50); // long jobWcet = ThreadLocalRandom.current().nextLong(20, 50);
Segment s = mock(Segment.class); // Segment s = mock(Segment.class);
when(s.getJobWcet()).thenReturn(jobWcet); // when(s.getJobWcet()).thenReturn(jobWcet);
SegmentContext sc = mock(SegmentContext.class); // SegmentContext sc = mock(SegmentContext.class);
when(sc.getSegment()).thenReturn(s); // when(sc.getSegment()).thenReturn(s);
TaskContext tc = mock(TaskContext.class); // TaskContext tc = mock(TaskContext.class);
when(tc.acceptNotification(anyLong())).thenReturn(Optional.of(tc)); // when(tc.acceptNotification(anyLong())).thenReturn(Optional.of(tc));
JobContext job = new JobContext(tc, sc); // JobContext job = new JobContext(tc, sc);
ProcessorContext p = mock(ProcessorContext.class); // ProcessorContext p = mock(ProcessorContext.class);
job.setCurrentProcessor(p); // job.setCurrentProcessor(p);
assertTrue(job.checkExecutionTime()); // assertTrue(job.checkExecutionTime());
for (int i = 0; i < jobWcet - 1; ++i) { // for (int i = 0; i < jobWcet - 1; ++i) {
assertFalse(job.updateExecution(i).isPresent()); // assertFalse(job.updateExecution(i).isPresent());
} // }
Optional<TaskContextInterface> otc = job.updateExecution(0); // Optional<ITaskContext> otc = job.updateExecution(0);
assertTrue(otc.isPresent()); // assertTrue(otc.isPresent());
assertTrue(tc.equals(otc.get())); // assertTrue(tc.equals(otc.get()));
assertFalse(p.getJob().isPresent()); // assertFalse(p.getSubtask().isPresent());
assertFalse(job.getCurrentProcessor().isPresent()); // assertFalse(job.getCurrentProcessor().isPresent());
assertFalse(job.checkExecutionTime()); // assertFalse(job.checkExecutionTime());
verify(p, times(1)).setJob(null); // verify(p, times(1)).setJob(null);
assertThrows(RuntimeException.class, () -> job.updateExecution(1)); // assertThrows(RuntimeException.class, () -> job.updateExecution(1));
} // }
} // }
} // }
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