package mvd.jester.simulator; import java.util.Comparator; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import com.google.common.collect.TreeMultiset; import mvd.jester.model.SystemManager; import mvd.jester.priority.PriorityManager; import mvd.jester.priority.RateMonotonic; import mvd.jester.TypeInterface; import mvd.jester.info.SchedulingInfo; import mvd.jester.simulator.internals.ProcessorContext; import mvd.jester.simulator.internals.TaskContextInterface; /** * AbstractSimulator */ public abstract class AbstractSimulator implements SimulatorInterface, TypeInterface { protected final SystemManager systemSetup; protected final Set processors; protected TreeMultiset readyTasks; AbstractSimulator(SystemManager systemSetup) { this.systemSetup = systemSetup; this.readyTasks = TreeMultiset.create((t1, t2) -> new RateMonotonic().compare(t1, t2)); processors = new HashSet<>(); for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) { processors.add(new ProcessorContext(i)); } } protected abstract boolean releaseTasks(long timeStep); @Override public SchedulingInfo runSimulation(PriorityManager priorityManager) { // SchedulingInfo schedulingInfo = new SchedulingInfo(systemSetup.getParallelTaskRatio(), // systemSetup.getUtilization()); // long hyperPeriod = init(priorityManager); // for (int t = 0; t < hyperPeriod; ++t) { // if (!releaseTasks(t)) { // throw new RuntimeException("Could not release a task. This should not happen!"); // } // Set sortedProcessors = sortProcessors(processors); // for (ProcessorContext p : sortedProcessors) { // for (TaskContextInterface tc : readyTasks) { // if (p.acceptTask(tc, t)) { // break; // } // } // } // for (ProcessorContext p : processors) { // Optional optionalTc = p.updateExecution(t); // if (optionalTc.isPresent()) { // TaskContextInterface tc = optionalTc.get(); // if (t >= tc.getDeadline()) { // TerminationInfo terminationInfo = // new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t); // schedulingInfo.addTerminationInfo(terminationInfo); // EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!"); // schedulingInfo.setFailedTerminationInfo(terminationInfo); // return schedulingInfo; // } // readyTasks.remove(optionalTc.get()); // } // } // } // return schedulingInfo; return null; } private long init(PriorityManager priorityManager) { this.readyTasks = TreeMultiset.create((t1, t2) -> priorityManager.compare(t1, t2)); for (ProcessorContext p : processors) { p.setJob(null); } return getHyperPeriod(); } private Set sortProcessors(Set processors) { Set sortedProcessors = new TreeSet<>(new ProcessorComparator()); processors.forEach(p -> sortedProcessors.add(p)); return sortedProcessors; } private long getHyperPeriod() { // return // systemSetup.getTasks().stream().max(Comparator.comparing(SynchronousTask::getPeriod)) // .get().getPeriod() * 10; return 10; } private class ProcessorComparator implements Comparator { @Override public int compare(ProcessorContext p1, ProcessorContext p2) { if (!p1.getJob().isPresent()) { return -1; } else if (!p2.getJob().isPresent()) { return 1; } else { long p1Period = p1.getJob().get().getTaskContext().getTask().getPeriod(); long p2Period = p2.getJob().get().getTaskContext().getTask().getPeriod(); if (p1Period == p2Period) { return 1; } else { return (int) (p2.getJob().get().getTaskContext().getTask().getPeriod() - p1.getJob().get().getTaskContext().getTask().getPeriod()); } } } } }