1 | package de.uka.ipd.sdq.scheduler.resources.passive; |
2 | |
3 | import de.uka.ipd.sdq.scheduler.ISchedulableProcess; |
4 | import de.uka.ipd.sdq.scheduler.LoggingWrapper; |
5 | import de.uka.ipd.sdq.scheduler.SchedulerModel; |
6 | import de.uka.ipd.sdq.scheduler.events.IDelayedAction; |
7 | import de.uka.ipd.sdq.scheduler.priority.IPriorityBoost; |
8 | import de.uka.ipd.sdq.scheduler.processes.IActiveProcess; |
9 | import de.uka.ipd.sdq.scheduler.processes.impl.ProcessWithPriority; |
10 | import de.uka.ipd.sdq.scheduler.resources.active.SimActiveResource; |
11 | import de.uka.ipd.sdq.scheduler.sensors.IPassiveResourceSensor; |
12 | |
13 | public class SimUnfairPassiveResource extends SimAbstractPassiveResource { |
14 | |
15 | private double acquisition_demand; |
16 | private boolean isFifo; |
17 | private int available; |
18 | private PassiveResourceObservee observee; |
19 | |
20 | public SimUnfairPassiveResource(SchedulerModel model, int capacity, String name, String id, |
21 | IPriorityBoost priority_boost, SimActiveResource managing_resource, |
22 | double acquisition_demand, boolean isFifo) { |
23 | super(model, capacity, name, id, priority_boost, managing_resource); |
24 | this.acquisition_demand = acquisition_demand; |
25 | this.isFifo = isFifo; |
26 | available = capacity; |
27 | observee = new PassiveResourceObservee(); |
28 | } |
29 | |
30 | public boolean acquire(ISchedulableProcess sched_process, int num, |
31 | boolean timeout, double timeoutValue) { |
32 | |
33 | // AM: Copied from AbstractActiveResource: If simulation is stopped, |
34 | // allow all processes to finish |
35 | if (!getModel().getSimulationControl().isRunning()) { |
36 | // Do nothing, but allows calling process to complete |
37 | return true; |
38 | } |
39 | |
40 | observee.fireRequest(sched_process, num); |
41 | ProcessWithPriority process = (ProcessWithPriority) main_resource |
42 | .lookUp(sched_process); |
43 | if (num <= available) { |
44 | grantAccess(num, process); |
45 | return true; |
46 | } else { |
47 | LoggingWrapper.log("Process " + process + " is waiting for " + num |
48 | + " of " + this); |
49 | WaitingProcess waiting_process = new WaitingProcess(process, num); |
50 | fromRunningToWaiting(waiting_process, !isFifo); |
51 | process.getSchedulableProcess().passivate(); |
52 | return false; |
53 | } |
54 | } |
55 | |
56 | private void grantAccess(int num, ProcessWithPriority process) { |
57 | LoggingWrapper.log("Process " + process + " acquires " + num + " of " |
58 | + this); |
59 | punish(process); |
60 | boostPriority(process); |
61 | available -= num; |
62 | observee.fireAquire(process.getSchedulableProcess(), num); |
63 | assert available >= 0 : "More resource than available have been acquired!"; |
64 | } |
65 | |
66 | public void release(ISchedulableProcess sched_process, int num) { |
67 | |
68 | // AM: Copied from AbstractActiveResource: If simulation is stopped, |
69 | // allow all processes to finish |
70 | if (!getModel().getSimulationControl().isRunning()) { |
71 | // Do nothing, but allows calling process to complete |
72 | return; |
73 | } |
74 | |
75 | LoggingWrapper.log("Process " + sched_process + " releases " + num |
76 | + " of " + this); |
77 | available += num; |
78 | observee.fireRelease(sched_process, num); |
79 | notifyNextWaitingProcess(); |
80 | } |
81 | |
82 | private void notifyNextWaitingProcess() { |
83 | WaitingProcess waiting_process = waiting_queue.peek(); |
84 | if (waiting_process != null) { |
85 | IActiveProcess process = waiting_process.getProcess(); |
86 | process.setCurrentDemand(acquisition_demand); |
87 | process.setDelayedAction(new UnfairAccessAction(waiting_process)); |
88 | fromWaitingToReady(waiting_process, process.getLastInstance()); |
89 | } |
90 | } |
91 | |
92 | /** |
93 | * Tries to remove the given process from the waiting queue and get access |
94 | * of the required number of passive resources. |
95 | * |
96 | * @param waitingProcess |
97 | * @return True if the process was successfully dequeued and activated, |
98 | * otherwise false. |
99 | */ |
100 | protected boolean tryToDequeueProcess(WaitingProcess waitingProcess) { |
101 | if (waitingProcess.getNumRequested() <= available) { |
102 | grantAccess(waitingProcess.getNumRequested(), |
103 | (ProcessWithPriority) waitingProcess.getProcess()); |
104 | if (available > 0) |
105 | notifyNextWaitingProcess(); |
106 | return true; |
107 | } else { |
108 | return false; |
109 | } |
110 | } |
111 | |
112 | private class UnfairAccessAction implements IDelayedAction { |
113 | private WaitingProcess waiting_process; |
114 | |
115 | public UnfairAccessAction(WaitingProcess waiting_process) { |
116 | super(); |
117 | this.waiting_process = waiting_process; |
118 | } |
119 | |
120 | public boolean perform() { |
121 | if (!tryToDequeueProcess(waiting_process)) { |
122 | fromRunningToWaiting(waiting_process, true); |
123 | return false; |
124 | } else { |
125 | waiting_process.getProcess().getSchedulableProcess().activate(); |
126 | return true; |
127 | } |
128 | } |
129 | } |
130 | |
131 | public void addObserver(IPassiveResourceSensor observer) { |
132 | observee.addObserver(observer); |
133 | } |
134 | |
135 | public void removeObserver(IPassiveResourceSensor observer) { |
136 | observee.removeObserver(observer); |
137 | } |
138 | |
139 | public int getAvailable() { |
140 | return available; |
141 | } |
142 | |
143 | } |