AbstractSimulator.java 4.47 KB
Newer Older
1 2
package mvd.jester.simulator;

3
import java.util.Comparator;
4
import java.util.HashSet;
5
import java.util.Optional;
6
import java.util.Set;
7
import java.util.TreeSet;
8
import com.google.common.collect.TreeMultiset;
9
import mvd.jester.model.SystemSetup;
10 11
import mvd.jester.model.Task;
import mvd.jester.priority.PriorityManager;
12
import mvd.jester.priority.RateMonotonic;
13 14 15
import mvd.jester.PairInterface;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo;
16
import mvd.jester.simulator.internals.ProcessorContext;
17
import mvd.jester.simulator.internals.TaskContextInterface;
18 19 20 21 22


/**
 * AbstractSimulator
 */
23
public abstract class AbstractSimulator implements SimulatorInterface, PairInterface {
24 25 26

    protected final SystemSetup systemSetup;
    protected final Set<ProcessorContext> processors;
27
    protected TreeMultiset<TaskContextInterface> readyTasks;
28
    protected long hyperPeriod;
29 30 31

    AbstractSimulator(SystemSetup systemSetup) {
        this.systemSetup = systemSetup;
32
        this.readyTasks = TreeMultiset.create((t1, t2) -> new RateMonotonic().compare(t1, t2));
33 34 35 36
        processors = new HashSet<>();
        for (int i = 0; i < systemSetup.getNumberOfProcessors(); ++i) {
            processors.add(new ProcessorContext(i));
        }
37 38
        this.hyperPeriod = getHyperPeriod();

39 40
    }

41 42 43 44

    protected abstract boolean releaseTasks(long timeStep);

    @Override
45 46
    public SchedulingInfo runSimulation(PriorityManager priorityManager) {
        SchedulingInfo schedulingInfo = new SchedulingInfo();
47
        init(priorityManager);
48 49
        for (int t = 0; t < hyperPeriod; ++t) {
            if (!releaseTasks(t)) {
50
                throw new RuntimeException("Could not release a task. This should not happen!");
51 52
            }

53
            Set<ProcessorContext> sortedProcessors = sortProcessors(processors);
54 55 56 57 58 59 60 61 62 63 64 65 66 67

            for (ProcessorContext p : sortedProcessors) {
                for (TaskContextInterface tc : readyTasks) {
                    if (p.acceptTask(tc, t)) {
                        break;
                    }
                }

            }

            for (ProcessorContext p : processors) {
                Optional<TaskContextInterface> optionalTc = p.updateExecution(t);
                if (optionalTc.isPresent()) {
                    TaskContextInterface tc = optionalTc.get();
68 69 70
                    TerminationInfo terminationInfo =
                            new TerminationInfo(tc.getReleaseTime(), tc.getDeadline(), t);
                    schedulingInfo.addTerminationInfo(terminationInfo);
71
                    if (t >= tc.getDeadline()) {
72
                        EventPrinter.print("Time " + t + ": Task " + tc + " failed its deadline!");
73 74
                        schedulingInfo.setFailedTemrinationInfo(terminationInfo);
                        return schedulingInfo;
75
                    }
76

77 78 79 80 81
                    readyTasks.remove(optionalTc.get());
                }
            }
        }

82
        return schedulingInfo;
83 84
    }

85
    private void init(PriorityManager priorityManager) {
86
        this.readyTasks = TreeMultiset.create((t1, t2) -> priorityManager.compare(t1, t2));
87 88 89
        for (ProcessorContext p : processors) {
            p.setJob(null);
        }
90
        this.hyperPeriod = getHyperPeriod();
91
    }
92

93 94
    private Set<ProcessorContext> sortProcessors(Set<ProcessorContext> processors) {
        Set<ProcessorContext> sortedProcessors = new TreeSet<>(new ProcessorComparator());
95

96 97 98 99 100
        processors.forEach(p -> sortedProcessors.add(p));

        return sortedProcessors;
    }

101 102
    private long getHyperPeriod() {
        return systemSetup.getTasks().stream().max(Comparator.comparing(Task::getPeriod)).get()
103
                .getPeriod() * 10;
104 105
    }

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    private class ProcessorComparator implements Comparator<ProcessorContext> {

        @Override
        public int compare(ProcessorContext p1, ProcessorContext p2) {
            if (!p1.getJob().isPresent()) {
                return -1;
            } else if (!p2.getJob().isPresent()) {
                return 1;
            } else {
                long p1Period = p1.getJob().get().getTaskContext().getTask().getPeriod();
                long p2Period = p2.getJob().get().getTaskContext().getTask().getPeriod();
                if (p1Period == p2Period) {
                    return 1;
                } else {
                    return (int) (p2.getJob().get().getTaskContext().getTask().getPeriod()
                            - p1.getJob().get().getTaskContext().getTask().getPeriod());
                }
            }
        }

    }
127
}