1 | package de.uka.ipd.sdq.scheduler.resources.active; |
2 | |
3 | import java.util.ArrayDeque; |
4 | import java.util.ArrayList; |
5 | import java.util.Deque; |
6 | import java.util.List; |
7 | |
8 | import org.apache.log4j.Logger; |
9 | |
10 | import de.uka.ipd.sdq.probfunction.math.util.MathTools; |
11 | import de.uka.ipd.sdq.scheduler.IRunningProcess; |
12 | import de.uka.ipd.sdq.scheduler.ISchedulableProcess; |
13 | import de.uka.ipd.sdq.scheduler.LoggingWrapper; |
14 | import de.uka.ipd.sdq.scheduler.SchedulerModel; |
15 | import de.uka.ipd.sdq.scheduler.processes.IActiveProcess; |
16 | import de.uka.ipd.sdq.scheduler.processes.impl.ActiveProcess; |
17 | import de.uka.ipd.sdq.scheduler.processes.impl.ProcessRegistry; |
18 | import de.uka.ipd.sdq.scheduler.resources.IResourceInstance; |
19 | import de.uka.ipd.sdq.scheduler.resources.passive.WaitingProcess; |
20 | import de.uka.ipd.sdq.scheduler.sensors.IActiveResourceStateSensor; |
21 | import de.uka.ipd.sdq.scheduler.strategy.IScheduler; |
22 | |
23 | public class SimActiveResource extends AbstractActiveResource { |
24 | |
25 | private IScheduler scheduler; |
26 | private List<IResourceInstance> instanceList; |
27 | private ProcessRegistry processRegistry; |
28 | private IResourceInstance main_instance; |
29 | private Deque<WaitingProcess> waiting_queue = new ArrayDeque<WaitingProcess>(); |
30 | |
31 | public static final Logger logger = Logger.getLogger("Scheduler"); |
32 | |
33 | public SimActiveResource(SchedulerModel model, int capacity, String name, String id) { |
34 | super(model, capacity, name, id); |
35 | this.instanceList = new ArrayList<IResourceInstance>(); |
36 | this.processRegistry = new ProcessRegistry(this); |
37 | for (int i = 0; i < capacity; i++) { |
38 | instanceList.add(factory.createResourceInstance(i, this)); |
39 | } |
40 | main_instance = instanceList.get(0); |
41 | } |
42 | |
43 | public IScheduler getScheduler() { |
44 | return scheduler; |
45 | } |
46 | |
47 | public List<IResourceInstance> getInstanceList() { |
48 | return instanceList; |
49 | } |
50 | |
51 | public IActiveProcess lookUp(ISchedulableProcess process) { |
52 | IActiveProcess p = processRegistry.lookUp(process); |
53 | if (p == null){ |
54 | ISchedulableProcess parent = process; |
55 | IActiveProcess pparent = null; |
56 | int i=0; |
57 | do{ |
58 | parent = parent.getRootProcess(); |
59 | pparent = processRegistry.lookUp(parent); |
60 | i++; |
61 | } while (pparent == null && parent != null); |
62 | assert pparent != null; |
63 | assert i < 2; |
64 | p = pparent.createNewInstance(process); |
65 | processRegistry.registerProcess(p); |
66 | } |
67 | return p; |
68 | } |
69 | |
70 | @Override |
71 | public void doProcessing(ISchedulableProcess sched_process, int resourceServiceID, double demand) { |
72 | IActiveProcess process = lookUp(sched_process); |
73 | |
74 | LoggingWrapper.log(" Process " + process + " demands " |
75 | + MathTools.round(demand, 0.01)); |
76 | |
77 | process.setCurrentDemand(demand); |
78 | scheduler.scheduleNextEvent(process.getLastInstance()); |
79 | sched_process.passivate(); |
80 | } |
81 | |
82 | public void start() { |
83 | for (IResourceInstance instance : this.instanceList) { |
84 | instance.start(); |
85 | } |
86 | } |
87 | |
88 | public boolean isIdle(IResourceInstance instance) { |
89 | return this.scheduler.isIdle(instance); |
90 | } |
91 | |
92 | public void setScheduler(IScheduler scheduler) { |
93 | this.scheduler = scheduler; |
94 | } |
95 | |
96 | @Override |
97 | protected void dequeue(ISchedulableProcess process) { |
98 | ActiveProcess myProcess = (ActiveProcess)lookUp(process); |
99 | WaitingProcess waiting_process = new WaitingProcess(myProcess,0); |
100 | scheduler.fromRunningToWaiting(waiting_process, waiting_queue, false); |
101 | // myProcess.setIdealInstance(null); |
102 | // myProcess.setLastInstance(null); |
103 | } |
104 | |
105 | @Override |
106 | protected void enqueue(ISchedulableProcess process) { |
107 | WaitingProcess waiting_process = lookUpWaitingProcess(process); |
108 | |
109 | if (waiting_process != null) { |
110 | IResourceInstance instance = getInstanceFor(waiting_process.getProcess()); |
111 | scheduler.fromWaitingToReady(waiting_process, waiting_queue, instance); |
112 | } else { |
113 | IActiveProcess p = lookUp(process); |
114 | IResourceInstance instance = getInstanceFor(p); |
115 | scheduler.forkNewProcess(p, instance); |
116 | instance.schedulingInterrupt(0); |
117 | } |
118 | } |
119 | |
120 | private IResourceInstance getInstanceFor(IActiveProcess process) { |
121 | IResourceInstance instance = main_instance; |
122 | if (process.hasIdealInstance()) |
123 | instance = process.getIdealInstance(); |
124 | if (process.hasLastInstance()) |
125 | instance = process.getLastInstance(); |
126 | return instance; |
127 | } |
128 | |
129 | private WaitingProcess lookUpWaitingProcess(ISchedulableProcess process) { |
130 | for (WaitingProcess p : waiting_queue){ |
131 | if (p.getProcess().getSchedulableProcess().equals(process)) |
132 | return p; |
133 | } |
134 | return null; |
135 | } |
136 | |
137 | public void stop() { |
138 | for( IResourceInstance ri : instanceList) { |
139 | ri.stop(); |
140 | } |
141 | } |
142 | |
143 | @Override |
144 | public double getRemainingDemand(ISchedulableProcess process) { |
145 | throw new UnsupportedOperationException("getRemainingDemand() not yet supported!"); |
146 | } |
147 | |
148 | @Override |
149 | public void updateDemand(ISchedulableProcess process, double demand) { |
150 | throw new UnsupportedOperationException("updateDemand() not yet supported!"); |
151 | } |
152 | |
153 | public void registerProcess(IRunningProcess runningProcess) { |
154 | IActiveProcess p = (IActiveProcess)runningProcess; |
155 | if (!processRegistry.isRegistered(p)){ |
156 | processRegistry.registerProcess(p); |
157 | IResourceInstance instance = getInstanceFor(p); |
158 | scheduler.registerProcess(p, instance); |
159 | p.getSchedulableProcess().addTerminatedObserver(this); |
160 | } |
161 | } |
162 | |
163 | public void unregisterProcess(IActiveProcess process) { |
164 | processRegistry.unregisterProcess(process.getSchedulableProcess()); |
165 | } |
166 | |
167 | public void addObserver(IActiveResourceStateSensor observer) { |
168 | for(IResourceInstance instance : this.instanceList){ |
169 | instance.addObserver(observer); |
170 | } |
171 | |
172 | } |
173 | |
174 | public IActiveProcess findProcess(String processName) { |
175 | return processRegistry.findProcess(processName); |
176 | } |
177 | |
178 | public void notifyTerminated(ISchedulableProcess simProcess) { |
179 | super.notifyTerminated(simProcess); |
180 | IActiveProcess activeProcess = lookUp(simProcess); |
181 | IResourceInstance instance = activeProcess.getLastInstance(); |
182 | getScheduler().terminateProcess(activeProcess, instance); |
183 | simProcess.removeTerminatedObserver(this); |
184 | } |
185 | |
186 | public int getQueueLengthFor(SimResourceInstance simResourceInstance) { |
187 | return this.scheduler.getQueueLengthFor(simResourceInstance); |
188 | } |
189 | } |