ChwaLee.java 4.64 KB
Newer Older
1 2 3 4 5
package mvd.jester.tests;

import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
6
import java.util.HashMap;
7 8
import java.util.HashSet;
import java.util.List;
9
import java.util.Map;
10
import java.util.Set;
11 12 13
import com.google.common.math.LongMath;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo;
14
import mvd.jester.info.TerminationInfo.Level;
15 16
import mvd.jester.model.Segment;
import mvd.jester.model.SortedTaskSet;
17 18
import mvd.jester.model.SynchronousTask;
import mvd.jester.priority.EarliestDeadlineFirst;
19 20 21 22 23
import mvd.jester.priority.PriorityManager;

/**
 * ChwaLee
 */
24
public class ChwaLee extends AbstractTest<SynchronousTask> {
25

26 27 28 29 30 31 32 33 34 35 36 37
    private final Map<SynchronousTask, TerminationInfo> responseTimes;
    private final PriorityManager priorityManager;

    public ChwaLee(long numberOfProcessors) {
        super(numberOfProcessors);
        this.responseTimes = new HashMap<>();
        this.priorityManager = new EarliestDeadlineFirst();
    }

    @Override
    public PriorityManager getPriorityManager() {
        return priorityManager;
38 39 40
    }

    @Override
41
    public SchedulingInfo runSchedulabilityCheck(SortedTaskSet<SynchronousTask> tasks) {
42
        responseTimes.clear();
43
        for (SynchronousTask t : tasks) {
44 45 46
            Level taskLevel = tasks.headSet(t).size() <= tasks.size() / 2 ? Level.HIGH : Level.LOW;
            long responseTime = calculateResponseTime(tasks, t);
            responseTimes.put(t, new TerminationInfo(t.getDeadline(), responseTime, taskLevel));
47 48 49
        }

        return new SchedulingInfo(new HashSet<>(responseTimes.values()),
50
                tasks.getParallelTaskRatio(), tasks.getUtilization());
51 52
    }

53
    private long calculateResponseTime(Set<SynchronousTask> tasks, SynchronousTask task) {
54 55 56 57 58
        long minimumWcet = getMinimumWcet(task);
        long deadline = task.getDeadline();

        long taskInterference = 0;

59
        for (SynchronousTask t : tasks) {
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
            if (!t.equals(task)) {
                long maxNumberOfJobs = t.getMaximumParallelism();
                for (long p = 0; p < maxNumberOfJobs; ++p) {
                    taskInterference += Math.min(getTaskInterference(t, deadline, p + 1),
                            deadline - minimumWcet);
                }
            }
        }

        long selfInterference = 0;

        long maxNumberOfJobs = task.getMaximumParallelism();

        for (long p = 0; p < maxNumberOfJobs; ++p) {
            selfInterference +=
                    Math.min(getSelfInterference(task, deadline, p + 1), deadline - minimumWcet);
        }

        boolean feasible = taskInterference + selfInterference <= numberOfProcessors
                * (deadline - minimumWcet);

        return feasible ? deadline - 1 : deadline + 1;
    }

84
    private long getSelfInterference(SynchronousTask task, long deadline, long p) {
85 86
        long selfInterference = 0;

87
        for (Segment s : task.getWorkloadDistribution()) {
88 89 90 91 92 93 94
            if (s.getNumberOfJobs() >= p + 1) {
                selfInterference += s.getJobWcet();
            }
        }
        return selfInterference;
    }

95
    private long getTaskInterference(SynchronousTask t, long deadline, long p) {
96 97 98 99
        long numberOfBodyJobs = LongMath.divide(deadline, t.getPeriod(), RoundingMode.FLOOR);

        long workloadOfBodyJobs = 0;

100
        for (Segment s : t.getWorkloadDistribution()) {
101 102 103 104 105 106 107 108 109
            if (s.getNumberOfJobs() >= p) {
                workloadOfBodyJobs += s.getJobWcet();
            }
        }

        long boundedBodyWorkload = numberOfBodyJobs * workloadOfBodyJobs;
        long boundedCarryInWorkload = 0;
        long remainingLength = deadline % t.getPeriod();
        long carryInLength = 0;
110
        List<Segment> segmentList = new ArrayList<>(t.getWorkloadDistribution());
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
        Collections.reverse(segmentList);
        for (Segment s : segmentList) {
            carryInLength += s.getJobWcet();
            if (s.getNumberOfJobs() >= p && remainingLength > carryInLength) {
                boundedCarryInWorkload += s.getJobWcet();
            } else if (s.getNumberOfJobs() >= p && remainingLength <= carryInLength) {
                boundedCarryInWorkload += s.getJobWcet() - (carryInLength - remainingLength);
            }
            if (carryInLength >= remainingLength) {
                break;
            }
        }

        return boundedBodyWorkload + boundedCarryInWorkload;
    }

127
    private long getMinimumWcet(SynchronousTask task) {
128
        long minWcet = 0;
129
        for (Segment s : task.getWorkloadDistribution()) {
130 131 132 133 134 135 136 137 138 139 140 141 142
            minWcet += s.getJobWcet();
        }

        return minWcet;
    }

    @Override
    public String getName() {
        return "ChwaLee";
    }


}