package mvd.jester.tests; import java.math.RoundingMode; import java.util.HashSet; import com.google.common.math.LongMath; import mvd.jester.info.SchedulingInfo; import mvd.jester.info.TerminationInfo; import mvd.jester.model.Segment; import mvd.jester.model.SortedTaskSet; import mvd.jester.model.Task; import mvd.jester.priority.PriorityManager; import mvd.jester.model.SystemSetup; /** * SchmidMottok */ public class SchmidMottok extends AbstractTest { public SchmidMottok(SystemSetup systemSetup) { super(systemSetup); } @Override public SchedulingInfo runSchedulabilityCheck(PriorityManager priorityManager) { tasks = new SortedTaskSet(priorityManager); tasks.addAll(systemSetup.getTasks()); responseTimes.clear(); for (Task t : tasks) { long responseTime = calculateResponseTime(t); responseTimes.put(t, new TerminationInfo(0, t.getDeadline(), responseTime)); } return new SchedulingInfo(new HashSet<>(responseTimes.values())); } @Override public String getName() { return "SchmidMottok"; } private long calculateResponseTime(Task task) { long minimumWcet = getMinimumWcet(task); long responseTime = minimumWcet; long previousResponseTime = 0; long numberOfProcessors = systemSetup.getNumberOfProcessors(); do { previousResponseTime = responseTime; double taskInterference = 0; for (Task t : tasks) { if (t.getPeriod() < task.getPeriod()) { long numberOfJobs = t.getMaximumParallelism() > numberOfProcessors ? numberOfProcessors : t.getMaximumParallelism(); for (int p = 0; p < numberOfJobs; ++p) { taskInterference += Math.min(getTaskInterference(t, responseTime, p + 1), responseTime - minimumWcet + 1); } } } taskInterference /= numberOfProcessors; double selfInterference = getSelfInterference(task); long totalInterference = (long) Math.floor(taskInterference + selfInterference); responseTime = minimumWcet + totalInterference; } while (previousResponseTime != responseTime); return responseTime; } private double getSelfInterference(Task task) { double interference = 0; long numberOfProcessors = systemSetup.getNumberOfProcessors(); long numberOfJobs = task.getMaximumParallelism() > numberOfProcessors ? numberOfProcessors : task.getMaximumParallelism(); for (Segment s : task.getSegments()) { interference += (double) (s.getNumberOfTasklets() - 1) * s.getTaskletWcet(); } interference /= numberOfJobs; return interference; } private double getTaskInterference(Task task, long interval, long parallelism) { if (responseTimes.containsKey(task)) { long responseTime = responseTimes.get(task).getResponseTime(); long minWcet = getMinimumWcet(task); long period = task.getPeriod(); long numberOfProcessors = systemSetup.getNumberOfProcessors(); long amountOfJobs = (LongMath.divide(interval + responseTime - minWcet, period, RoundingMode.FLOOR) + 1); double workload = 0; for (Segment s : task.getSegments()) { long numberOfJobs = s.getNumberOfJobs() > numberOfProcessors ? numberOfProcessors : s.getNumberOfJobs(); if (numberOfJobs >= parallelism) { workload += s.getNumberOfTasklets() * s.getTaskletWcet() / numberOfJobs; } } double interference = amountOfJobs * workload; return interference; } else { throw new RuntimeException("Task was not found in task set!"); } } private long getMinimumWcet(Task task) { long minWcet = 0; for (Segment s : task.getSegments()) { minWcet += s.getTaskletWcet(); } return minWcet; } }