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.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.SynchronousTask; import mvd.jester.model.SystemManager; import mvd.jester.priority.PriorityManager; import mvd.jester.priority.RateMonotonic; /** * MaiaBertogna */ public class MaiaBertogna extends AbstractTest { private final Map responseTimes; private final PriorityManager priorityManager; public MaiaBertogna(final SystemManager manager) { super(manager); this.responseTimes = new HashMap<>(); this.priorityManager = new RateMonotonic(); } @Override public PriorityManager getPriorityManager() { return priorityManager; } @Override public SchedulingInfo runSchedulabilityCheck(final SortedTaskSet tasks) { responseTimes.clear(); for (final SynchronousTask t : tasks) { final long responseTime = calculateResponseTime(tasks, t); responseTimes.put(t, new TerminationInfo(t.getDeadline(), responseTime)); } return new SchedulingInfo(responseTimes.values()); } @Override public String getName() { return "MaiaBertogna"; } private long calculateResponseTime(final Set tasks, final SynchronousTask task) { final long minimumWcet = getMinimumWcet(task); long responseTime = minimumWcet; long previousResponseTime = 0; do { previousResponseTime = responseTime; long taskInterference = 0; for (final SynchronousTask t : tasks) { if (t.getPeriod() < task.getPeriod()) { final long maxNumberOfJobsOfT = t.getMaximumParallelism(); for (int p = 0; p < maxNumberOfJobsOfT; ++p) { taskInterference += Math.min(getTaskInterference(t, responseTime, p + 1), responseTime - minimumWcet + 1); } } } long selfInterference = 0; final long maxNumberOfJobs = task.getMaximumParallelism(); for (int p = 0; p < maxNumberOfJobs; ++p) { selfInterference += Math.min(getSelfInterference(task, p + 1), responseTime - minimumWcet + 1); } final long totalInterference = LongMath.divide(taskInterference + selfInterference, manager.getNumberOfProcessors(), RoundingMode.FLOOR); responseTime = minimumWcet + totalInterference; } while (previousResponseTime != responseTime); return responseTime; } private long getSelfInterference(final SynchronousTask task, final long parallelism) { long interference = 0; for (final Segment s : task.getWorkloadDistribution()) { if (s.getNumberOfJobs() >= parallelism + 1) { interference += s.getJobWcet(); } } return interference; } private long getTaskInterference(final SynchronousTask task, final long interval, final long parallelism) { if (responseTimes.containsKey(task)) { final long responseTime = responseTimes.get(task).getResponseTime(); final long minWcet = getMinimumWcet(task); final long period = task.getPeriod(); final long numberOfJobs = (LongMath.divide(interval + responseTime - minWcet, period, RoundingMode.FLOOR) + 1); long workload = 0; for (final Segment s : task.getWorkloadDistribution()) { if (s.getNumberOfJobs() >= parallelism) { workload += s.getJobWcet(); } } final long interference = numberOfJobs * workload; return interference; } else { throw new RuntimeException("Task was not found in task set!"); } } private long getMinimumWcet(final SynchronousTask task) { long minWcet = 0; for (final Segment s : task.getWorkloadDistribution()) { minWcet += s.getJobWcet(); } return minWcet; } }