SchmidMottok.java 4.38 KB
Newer Older
1 2
package mvd.jester.tests;

3
import java.math.RoundingMode;
4 5
import java.util.HashMap;
import java.util.Map;
6
import java.util.Set;
7
import com.google.common.math.LongMath;
8 9
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo;
10
import mvd.jester.model.DagTask;
11
import mvd.jester.model.SortedTaskSet;
12
import mvd.jester.model.SystemManagerInterface;
13
import mvd.jester.model.Task;
14
import mvd.jester.priority.PriorityManager;
15
import mvd.jester.priority.RateMonotonic;
16 17 18 19

/**
 * SchmidMottok
 */
20
public class SchmidMottok extends AbstractTest<DagTask> {
21

22 23
    private final Map<Task, TerminationInfo> responseTimes;
    private final PriorityManager priorityManager;
24
    private final TypeFunction structure;
25

26
    public SchmidMottok(TypeFunction structure, final SystemManagerInterface manager) {
Michael Schmid committed
27
        super(manager);
28 29
        this.responseTimes = new HashMap<>();
        this.priorityManager = new RateMonotonic();
30
        this.structure = structure;
31 32 33
    }

    @Override
34 35 36 37 38
    public PriorityManager getPriorityManager() {
        return priorityManager;
    }

    @Override
39
    public SchedulingInfo runSchedulabilityCheck(final SortedTaskSet<DagTask> tasks) {
40
        responseTimes.clear();
41
        reassignNumberOfThreads(tasks);
42 43 44
        for (final DagTask t : tasks) {
            final long responseTime = calculateResponseTime(tasks, t);
            responseTimes.put(t, new TerminationInfo(t.getDeadline(), responseTime));
45 46
        }

47
        return new SchedulingInfo(responseTimes.values());
48 49 50 51
    }

    @Override
    public String getName() {
52
        return "SchmidMottok" + "_" + structure.getType();
53 54
    }

55 56 57 58 59 60 61 62 63 64 65 66
    private void reassignNumberOfThreads(Set<DagTask> tasks) {
        long numberOfProcessors = manager.getNumberOfProcessors();
        long occupiedProcessors = 0;
        for (DagTask t : tasks) {
            if (occupiedProcessors >= numberOfProcessors) {
                t.setNumberOfThreads(numberOfProcessors);
            } else {
                occupiedProcessors += t.getNumberOfThreads();
            }
        }
    }

67 68
    private long calculateResponseTime(final Set<DagTask> tasks, final DagTask task) {
        final long minimumWcet = task.getCriticalPath();
69 70
        long responseTime = minimumWcet;
        long previousResponseTime = 0;
71 72 73 74 75 76 77 78 79
        final long numberOfProcessors = manager.getNumberOfProcessors();

        long occupiedProcessors = 0;
        for (final DagTask t : tasks) {
            if (t.getPeriod() < task.getPeriod()) {
                final long numberOfThreads = structure.getNumberOfThreads(t);
                occupiedProcessors += numberOfThreads;
            }
        }
80

81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        final double selfInterference = structure.getSelfInterference(task);

        if (occupiedProcessors + structure.getNumberOfThreads(task) <= numberOfProcessors) {
            return minimumWcet + (long) Math.floor(selfInterference);
        } else {
            do {
                previousResponseTime = responseTime;
                double taskInterference = 0;

                for (final DagTask t : tasks) {
                    if (t.getPeriod() < task.getPeriod()) {
                        final long numberOfThreads = structure.getNumberOfThreads(t);
                        for (int p = 0; p < numberOfThreads; ++p) {
                            taskInterference +=
                                    Math.min(
                                            structure.getTaskInterference(t, responseTimes,
                                                    responseTime, p + 1),
                                            responseTime - minimumWcet + 1);
                        }
Michael Schmid committed
100
                    }
101 102
                }

103
                taskInterference /= numberOfProcessors;
104

105
                long totalInterference = (long) Math.floor(taskInterference + selfInterference);
106

107 108 109 110 111 112 113
                if (occupiedProcessors < numberOfProcessors) {
                    long workloadAmongRemainingProcessors =
                            LongMath.divide(task.getWorkload() - task.getCriticalPath(),
                                    numberOfProcessors - occupiedProcessors, RoundingMode.FLOOR);
                    totalInterference =
                            Math.min(totalInterference, workloadAmongRemainingProcessors);
                }
114

115 116
                responseTime = minimumWcet + totalInterference;
            } while (previousResponseTime != responseTime);
117

118 119 120
            return responseTime;
        }
    }
121
}