1 | package de.uka.ipd.sdq.scheduler.queueing.runqueues; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.List; |
5 | |
6 | import de.uka.ipd.sdq.scheduler.SchedulerModel; |
7 | import de.uka.ipd.sdq.scheduler.processes.IActiveProcess; |
8 | import de.uka.ipd.sdq.scheduler.processes.impl.PreemptiveProcess; |
9 | import de.uka.ipd.sdq.scheduler.queueing.IProcessQueue; |
10 | import de.uka.ipd.sdq.scheduler.queueing.IRunQueue; |
11 | import de.uka.ipd.sdq.scheduler.resources.IResourceInstance; |
12 | |
13 | public class ActiveExpiredRunQueue extends AbstractRunQueue { |
14 | |
15 | private SchedulerModel model; |
16 | private IProcessQueue activePriorityArray; |
17 | private IProcessQueue expiredPriorityArray; |
18 | private double expired_timestamp = -1; |
19 | |
20 | public ActiveExpiredRunQueue(SchedulerModel model, IProcessQueue queue_prototype) { |
21 | this.model = model; |
22 | this.activePriorityArray = queue_prototype.createNewInstance(); |
23 | this.expiredPriorityArray = queue_prototype.createNewInstance(); |
24 | } |
25 | |
26 | /** |
27 | * Adds a new process to the end of the expired priority array. |
28 | */ |
29 | @Override |
30 | public void addProcessToRunQueue(IActiveProcess process, boolean inFront) { |
31 | |
32 | if (((PreemptiveProcess) process).getTimeslice().isFinished()) { |
33 | updateStarvationTime(); |
34 | } |
35 | if (process instanceof PreemptiveProcess) { |
36 | PreemptiveProcess preemptiveProcess = (PreemptiveProcess) process; |
37 | if (preemptiveProcess.getTimeslice().isFinished()) { |
38 | expiredPriorityArray.add(process, inFront); |
39 | } else { |
40 | activePriorityArray.add(process, inFront); |
41 | } |
42 | } else { |
43 | expiredPriorityArray.add(process, inFront); |
44 | } |
45 | } |
46 | |
47 | @Override |
48 | protected int numWaitingProcesses() { |
49 | return activePriorityArray.size() + expiredPriorityArray.size(); |
50 | } |
51 | |
52 | @Override |
53 | public IActiveProcess getNextRunnableProcess(IResourceInstance instance) { |
54 | if (activeQueueEmpty()) |
55 | switchActiveAndExpired(); |
56 | if (activePriorityArray.isEmpty()) // no process to be scheduled. |
57 | return null; |
58 | return activePriorityArray.getNextRunnableProcess(instance); |
59 | } |
60 | |
61 | public IActiveProcess getNextRunnableProcess() { |
62 | if (activeQueueEmpty()) |
63 | switchActiveAndExpired(); |
64 | if (activePriorityArray.isEmpty()) // no process to be scheduled. |
65 | return null; |
66 | return activePriorityArray.getNextRunnableProcess(); |
67 | } |
68 | |
69 | private void switchActiveAndExpired() { |
70 | IProcessQueue temp = activePriorityArray; |
71 | activePriorityArray = expiredPriorityArray; |
72 | expiredPriorityArray = temp; |
73 | resetStarvationInfo(); |
74 | } |
75 | |
76 | @Override |
77 | public boolean removePendingProcess(IActiveProcess process) { |
78 | return activePriorityArray.remove(process) |
79 | || expiredPriorityArray.remove(process); |
80 | } |
81 | |
82 | /** |
83 | * Determines whether the current active queue is empty including the |
84 | * running and standby processes. |
85 | */ |
86 | protected boolean activeQueueEmpty() { |
87 | return running_on_table.isEmpty() && activePriorityArray.isEmpty(); |
88 | } |
89 | |
90 | public IRunQueue createNewInstance() { |
91 | return new ActiveExpiredRunQueue(model, activePriorityArray); |
92 | } |
93 | |
94 | public List<IActiveProcess> identifyMovableProcesses( |
95 | IResourceInstance targetInstance, boolean prio_increasing, |
96 | boolean queue_ascending, int processes_needed) { |
97 | List<IActiveProcess> process_list = new ArrayList<IActiveProcess>(); |
98 | expiredPriorityArray.identifyMovableProcesses(targetInstance, |
99 | prio_increasing, queue_ascending, processes_needed, |
100 | process_list); |
101 | activePriorityArray.identifyMovableProcesses(targetInstance, |
102 | prio_increasing, queue_ascending, processes_needed, |
103 | process_list); |
104 | return process_list; |
105 | } |
106 | |
107 | public IProcessQueue getBestRunnableQueue(IResourceInstance instance) { |
108 | IProcessQueue result = activePriorityArray |
109 | .getBestRunnableQueue(instance); |
110 | if (result == null) { |
111 | result = expiredPriorityArray.getBestRunnableQueue(instance); |
112 | } |
113 | return result; |
114 | } |
115 | |
116 | @Override |
117 | public boolean containsPending(IActiveProcess process) { |
118 | return activePriorityArray.contains(process) |
119 | || expiredPriorityArray.contains(process); |
120 | } |
121 | |
122 | public boolean processStarving(double threshold) { |
123 | if (expired_timestamp >= 0) { |
124 | double simTime = model.getSimulationControl().getCurrentSimulationTime(); |
125 | return simTime - expired_timestamp > threshold; |
126 | } else { |
127 | return false; |
128 | } |
129 | } |
130 | |
131 | public List<IActiveProcess> getStarvingProcesses(double starvationLimit) { |
132 | List<IActiveProcess> result = expiredPriorityArray |
133 | .getStarvingProcesses(starvationLimit); |
134 | result |
135 | .addAll(activePriorityArray |
136 | .getStarvingProcesses(starvationLimit)); |
137 | return result; |
138 | } |
139 | |
140 | public void setWaitingTime(IActiveProcess process, double waiting) { |
141 | if (expiredPriorityArray.contains(process)) { |
142 | expiredPriorityArray.setWaitingTime(process, waiting); |
143 | } else { |
144 | activePriorityArray.setWaitingTime(process, waiting); |
145 | } |
146 | } |
147 | |
148 | public double getWaitingTime(IActiveProcess process) { |
149 | if (expiredPriorityArray.contains(process)) { |
150 | return expiredPriorityArray.getWaitingTime(process); |
151 | } else { |
152 | return activePriorityArray.getWaitingTime(process); |
153 | } |
154 | } |
155 | |
156 | public void resetStarvationInfo() { |
157 | expired_timestamp = -1; |
158 | } |
159 | |
160 | private void updateStarvationTime() { |
161 | double simTime = model.getSimulationControl().getCurrentSimulationTime(); |
162 | updateStarvationTime(simTime); |
163 | } |
164 | |
165 | private void updateStarvationTime(double waiting) { |
166 | if (expired_timestamp < 0) { |
167 | expired_timestamp = waiting; |
168 | } |
169 | } |
170 | |
171 | } |