1 | package de.uka.ipd.sdq.scheduler.queueing.basicqueues; |
2 | |
3 | import java.util.ArrayDeque; |
4 | import java.util.ArrayList; |
5 | import java.util.Hashtable; |
6 | import java.util.Iterator; |
7 | import java.util.List; |
8 | |
9 | import de.uka.ipd.sdq.scheduler.SchedulerModel; |
10 | import de.uka.ipd.sdq.scheduler.processes.IActiveProcess; |
11 | import de.uka.ipd.sdq.scheduler.queueing.IProcessQueue; |
12 | import de.uka.ipd.sdq.scheduler.resources.IResourceInstance; |
13 | |
14 | public class ProcessQueueImpl implements IProcessQueue { |
15 | |
16 | private SchedulerModel model; |
17 | private ArrayDeque<IActiveProcess> queue; |
18 | private Hashtable<IActiveProcess, Double> waiting_time_table = new Hashtable<IActiveProcess, Double>(); |
19 | |
20 | public ProcessQueueImpl(SchedulerModel model) { |
21 | this.model = model; |
22 | this.queue = new ArrayDeque<IActiveProcess>(); |
23 | } |
24 | |
25 | public void addLast(IActiveProcess process) { |
26 | waiting_time_table.put(process, model.getSimulationControl().getCurrentSimulationTime()); |
27 | queue.addLast(process); |
28 | } |
29 | |
30 | public void addFirst(IActiveProcess process) { |
31 | waiting_time_table.put(process, model.getSimulationControl().getCurrentSimulationTime()); |
32 | queue.addFirst(process); |
33 | } |
34 | |
35 | public void add(IActiveProcess process, boolean inFront){ |
36 | if (inFront) |
37 | addFirst(process); |
38 | else |
39 | addLast(process); |
40 | } |
41 | |
42 | public IActiveProcess peek() { |
43 | return queue.peek(); |
44 | } |
45 | |
46 | public IActiveProcess poll() { |
47 | IActiveProcess process = queue.poll(); |
48 | waiting_time_table.remove(process); |
49 | return process; |
50 | } |
51 | |
52 | public int size() { |
53 | return queue.size(); |
54 | } |
55 | |
56 | public boolean remove(IActiveProcess process) { |
57 | waiting_time_table.remove(process); |
58 | return queue.remove(process); |
59 | } |
60 | |
61 | public boolean isEmpty() { |
62 | return queue.isEmpty(); |
63 | } |
64 | |
65 | public Iterable<IActiveProcess> ascending(){ |
66 | return new Iterable<IActiveProcess>(){ |
67 | public Iterator<IActiveProcess> iterator() { |
68 | return queue.iterator(); |
69 | } |
70 | }; |
71 | } |
72 | |
73 | public Iterable<IActiveProcess> descending(){ |
74 | return new Iterable<IActiveProcess>(){ |
75 | public Iterator<IActiveProcess> iterator() { |
76 | return queue.descendingIterator(); |
77 | } |
78 | }; |
79 | } |
80 | |
81 | @SuppressWarnings("unchecked") |
82 | private boolean containsRunnableFor(IResourceInstance instance) { |
83 | Iterator iterator = this.queue.iterator(); |
84 | while(iterator.hasNext()){ |
85 | IActiveProcess process = (IActiveProcess)iterator.next(); |
86 | if(process.checkAffinity(instance)) |
87 | return true; |
88 | } |
89 | return false; |
90 | } |
91 | |
92 | public boolean contains(IActiveProcess process) { |
93 | return queue.contains(process); |
94 | } |
95 | |
96 | public IProcessQueue getBestRunnableQueue(IResourceInstance instance) { |
97 | if (containsRunnableFor(instance)) |
98 | return this; |
99 | return null; |
100 | } |
101 | |
102 | public IActiveProcess getNextRunnableProcess(IResourceInstance instance) { |
103 | for (IActiveProcess process : ascending()) { |
104 | if (process.checkAffinity(instance)) |
105 | return process; |
106 | } |
107 | return null; |
108 | } |
109 | |
110 | public IActiveProcess getNextRunnableProcess() { |
111 | return peek(); |
112 | } |
113 | |
114 | public void identifyMovableProcesses( |
115 | IResourceInstance targetInstance, boolean prio_increasing, |
116 | boolean queue_ascending, int processes_needed, List<IActiveProcess> process_list) { |
117 | Iterable<IActiveProcess> queue_direction = queue_ascending ? ascending() : descending(); |
118 | for (IActiveProcess process : queue_direction) { |
119 | if (process.isMovable(targetInstance)) { |
120 | process_list.add(process); |
121 | if (process_list.size() >= processes_needed) |
122 | break; |
123 | } |
124 | } |
125 | } |
126 | |
127 | public IProcessQueue createNewInstance() { |
128 | return new ProcessQueueImpl(model); |
129 | } |
130 | |
131 | |
132 | public boolean processStarving(double threshold) { |
133 | double now = model.getSimulationControl().getCurrentSimulationTime(); |
134 | for (IActiveProcess process : ascending()){ |
135 | double waiting_time = now - waiting_time_table.get(process); |
136 | if (waiting_time > threshold) |
137 | return true; |
138 | } |
139 | return false; |
140 | } |
141 | |
142 | public void setWaitingTime(IActiveProcess process, double waiting) { |
143 | waiting_time_table.put(process, waiting); |
144 | } |
145 | |
146 | public double getWaitingTime(IActiveProcess process) { |
147 | return waiting_time_table.get(process); |
148 | } |
149 | |
150 | public List<IActiveProcess> getStarvingProcesses(double starvationLimit) { |
151 | double now = model.getSimulationControl().getCurrentSimulationTime(); |
152 | List<IActiveProcess> result = new ArrayList<IActiveProcess>(); |
153 | for (IActiveProcess process : ascending()){ |
154 | Double time = waiting_time_table.get(process); |
155 | double waiting_time = now - time; |
156 | if (waiting_time > starvationLimit){ |
157 | result.add(process); |
158 | } |
159 | } |
160 | return result; |
161 | } |
162 | } |