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; /** * MaiaBertogna */ public class MaiaBertogna extends AbstractTest { public MaiaBertogna(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 "MaiaBertogna"; } private long calculateResponseTime(Task task) { long minimumWcet = getMinimumWcet(task); long responseTime = minimumWcet; long previousResponseTime = 0; do { previousResponseTime = responseTime; long taskInterference = 0; for (Task t : tasks) { if (t.getPeriod() < task.getPeriod()) { 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; long maxNumberOfJobs = task.getMaximumParallelism(); for (int p = 0; p < maxNumberOfJobs; ++p) { selfInterference += Math.min(getSelfInterference(task, p + 1), responseTime - minimumWcet + 1); } long totalInterference = LongMath.divide(taskInterference + selfInterference, systemSetup.getNumberOfProcessors(), RoundingMode.FLOOR); responseTime = minimumWcet + totalInterference; } while (previousResponseTime != responseTime); return responseTime; } private long getSelfInterference(Task task, long parallelism) { long interference = 0; for (Segment s : task.getSegments()) { if (s.getNumberOfJobs() >= parallelism + 1) { interference += s.getJobWcet(); } } return interference; } private long 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 numberOfJobs = (LongMath.divide(interval + responseTime - minWcet, period, RoundingMode.FLOOR) + 1); long workload = 0; for (Segment s : task.getSegments()) { if (s.getNumberOfJobs() >= parallelism) { workload += s.getJobWcet(); } } long interference = numberOfJobs * 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.getJobWcet(); } return minWcet; } }