| 1 | package de.uka.ipd.sdq.scheduler.resources.active; |
| 2 | |
| 3 | import java.util.ArrayList; |
| 4 | import java.util.List; |
| 5 | import java.util.Map; |
| 6 | import java.util.concurrent.ConcurrentHashMap; |
| 7 | |
| 8 | import de.uka.ipd.sdq.scheduler.IActiveResource; |
| 9 | import de.uka.ipd.sdq.scheduler.ISchedulableProcess; |
| 10 | import de.uka.ipd.sdq.scheduler.SchedulerModel; |
| 11 | import de.uka.ipd.sdq.scheduler.resources.AbstractSimResource; |
| 12 | import de.uka.ipd.sdq.scheduler.sensors.IActiveResourceStateSensor; |
| 13 | |
| 14 | public abstract class AbstractActiveResource extends AbstractSimResource implements IActiveResource { |
| 15 | |
| 16 | private static Map<ISchedulableProcess, AbstractActiveResource> currentResourceTable = new ConcurrentHashMap<ISchedulableProcess, AbstractActiveResource>(); |
| 17 | |
| 18 | private List<IActiveResourceStateSensor> observers; |
| 19 | |
| 20 | public AbstractActiveResource(SchedulerModel model, int capacity, String name, String id) { |
| 21 | super(model, capacity, name, id); |
| 22 | observers = new ArrayList<IActiveResourceStateSensor>(); |
| 23 | } |
| 24 | |
| 25 | public final void process(ISchedulableProcess process, int resourceServiceID, double demand) { |
| 26 | if (!getModel().getSimulationControl().isRunning()) { |
| 27 | // Do nothing, but allows calling process to complete |
| 28 | return; |
| 29 | } |
| 30 | |
| 31 | AbstractActiveResource last = getLastResource(process); |
| 32 | if (!this.equals(last)) { |
| 33 | if (last != null) { |
| 34 | last.dequeue(process); |
| 35 | } |
| 36 | this.enqueue(process); |
| 37 | setLastResource(process, this); |
| 38 | } |
| 39 | doProcessing(process, resourceServiceID, demand); |
| 40 | } |
| 41 | |
| 42 | protected abstract void doProcessing(ISchedulableProcess process, int resourceServiceID, |
| 43 | double demand); |
| 44 | |
| 45 | protected abstract void enqueue(ISchedulableProcess process); |
| 46 | |
| 47 | protected abstract void dequeue(ISchedulableProcess process); |
| 48 | |
| 49 | private static AbstractActiveResource getLastResource( |
| 50 | ISchedulableProcess process) { |
| 51 | return currentResourceTable.get(process); |
| 52 | } |
| 53 | |
| 54 | private static void setLastResource(ISchedulableProcess process, |
| 55 | AbstractActiveResource resource) { |
| 56 | if (!currentResourceTable.containsKey(process)) { |
| 57 | process.addTerminatedObserver(resource); |
| 58 | } |
| 59 | currentResourceTable.put(process, resource); |
| 60 | } |
| 61 | |
| 62 | public static void cleanProcesses() { |
| 63 | // Activate all waiting processes to yield process completion |
| 64 | // Synchronization with process() avoids that processes are added after |
| 65 | // the activation. |
| 66 | for (ISchedulableProcess process : currentResourceTable.keySet()) { |
| 67 | if (!process.isFinished()) { |
| 68 | //TODO: to avoid exceptions at the end of the simulation, |
| 69 | // these are being caught here. Maybe something can be fixed |
| 70 | // in the simulation so that the exception does not occur here. |
| 71 | try { |
| 72 | process.activate(); |
| 73 | } catch (IllegalStateException e) { |
| 74 | |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | // assert that all threads have been terminated. |
| 80 | assert currentResourceTable.size() == 0; |
| 81 | } |
| 82 | |
| 83 | public void notifyTerminated(ISchedulableProcess simProcess) { |
| 84 | currentResourceTable.remove(simProcess); |
| 85 | } |
| 86 | |
| 87 | |
| 88 | public void addObserver(IActiveResourceStateSensor observer) { |
| 89 | this.observers.add(observer); |
| 90 | } |
| 91 | |
| 92 | public void removeObserver(IActiveResourceStateSensor observer) { |
| 93 | this.observers.remove(observer); |
| 94 | } |
| 95 | |
| 96 | protected void fireStateChange(int state, int instanceId) { |
| 97 | for (IActiveResourceStateSensor l : observers) { |
| 98 | l.update(state, instanceId); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | protected void fireDemandCompleted(ISchedulableProcess simProcess) { |
| 103 | for (IActiveResourceStateSensor l : observers) { |
| 104 | l.demandCompleted(simProcess); |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | } |