| 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 | } |