package mvd.jester.tests; import java.math.RoundingMode; import java.util.HashMap; import java.util.Map; import java.util.Set; import com.google.common.math.DoubleMath; import mvd.jester.info.SchedulingInfo; import mvd.jester.info.TerminationInfo; import mvd.jester.model.DagTask; import mvd.jester.model.SortedTaskSet; import mvd.jester.model.SystemManager; import mvd.jester.model.Task; import mvd.jester.priority.PriorityManager; import mvd.jester.priority.RateMonotonic; public class MelaniButtazzo extends AbstractTest { private final Map responseTimes; private final PriorityManager priorityManager; public MelaniButtazzo(final SystemManager manager) { super(manager); this.responseTimes = new HashMap<>(); this.priorityManager = new RateMonotonic(); } @Override public PriorityManager getPriorityManager() { return priorityManager; } @Override public String getName() { return "MelaniButtazzo"; } @Override public SchedulingInfo runSchedulabilityCheck(final SortedTaskSet tasks) { responseTimes.clear(); for (final DagTask t : tasks) { final long responseTime = calculateResponseTime(tasks, t); responseTimes.put(t, new TerminationInfo(t.getDeadline(), responseTime)); } return new SchedulingInfo(responseTimes.values()); } private long calculateResponseTime(final Set tasks, final DagTask task) { final long criticalPath = task.getCriticalPath(); long responseTime = criticalPath; long previousResponseTime = 0; do { previousResponseTime = responseTime; double taskInterference = 0; for (final DagTask t : tasks) { if (t.getPeriod() < task.getPeriod()) { taskInterference += getTaskInterference(t, responseTime); } } taskInterference /= manager.getNumberOfProcessors(); final double selfInterference = getSelfInterference(task); // TODO: Einzeln abrunden oder self interference als long abrunden final long totalInterference = (long) Math.floor(taskInterference + selfInterference); responseTime = criticalPath + totalInterference; } while (previousResponseTime != responseTime); return responseTime; } private double getSelfInterference(final DagTask task) { final long criticalPath = task.getCriticalPath(); final long workload = task.getWorkload(); return (double) (workload - criticalPath) / manager.getNumberOfProcessors(); } private double getTaskInterference(final DagTask task, final long interval) { if (responseTimes.containsKey(task)) { final long responseTime = responseTimes.get(task).getResponseTime(); final long singleWorkload = task.getWorkload(); final long period = task.getPeriod(); final double nominator = (interval + responseTime - (double) singleWorkload / manager.getNumberOfProcessors()); final long amountOfJobs = DoubleMath.roundToLong(nominator / period, RoundingMode.FLOOR); final double carryOutPortion = Math.min(singleWorkload, manager.getNumberOfProcessors() * (nominator % period)); final double interference = amountOfJobs * singleWorkload + carryOutPortion; return interference; } else { throw new RuntimeException("Task was not found in task set!"); } } }