1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.dsol.formalisms;
11
12 import java.rmi.RemoteException;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.Iterator;
16 import java.util.List;
17
18 import nl.tudelft.simulation.dsol.SimRuntimeException;
19 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
20 import nl.tudelft.simulation.event.EventProducer;
21 import nl.tudelft.simulation.event.EventType;
22
23 /***
24 * A resource defines a shared and limited amount.
25 * <p>
26 * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
27 * University of Technology </a>, the Netherlands. <br>
28 * See for project information <a href="http://www.simulation.tudelft.nl">
29 * www.simulation.tudelft.nl </a> <br>
30 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
31 * License (GPL) </a>, no warranty <br>
32 *
33 * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
34 * Jacobs </a>
35 * @version 1.2 2004-03-26
36 * @since 1.0
37 */
38 public class Resource extends EventProducer
39 {
40 /*** UTILIZATION_EVENT is fired on activity */
41 public static final EventType UTILIZATION_EVENT = new EventType(
42 "UTILIZATION_EVENT");
43
44 /*** RESOURCE_REQUESTED_QUEUE_LENGTH fired on changes in queue length */
45 public static final EventType RESOURCE_REQUESTED_QUEUE_LENGTH = new EventType(
46 "RESOURCE_REQUESTED_QUEUE_LENGTH");
47
48 /***
49 * capacity defines the maximuum capacity of the resource
50 *
51 * @uml.property name="capacity"
52 */
53 protected double capacity;
54
55
56 /*** claimedCapacity defines the currently claimed capacity */
57 protected double claimedCapacity = 0.0;
58
59 /*** request defines the list of requestors for this resource */
60 private List requests = Collections.synchronizedList(new ArrayList());
61
62 /*** simulator defines the simulator on which is scheduled */
63 protected DEVSSimulatorInterface simulator;
64
65 /*** the description of the resource */
66 protected String description = "resource";
67
68 /***
69 * Method Resource.
70 *
71 * @param simulator on which is scheduled
72 * @param description the description of this resource
73 * @param capacity of the resource
74 */
75 public Resource(final DEVSSimulatorInterface simulator,
76 final String description, final double capacity)
77 {
78 super();
79 this.description = description;
80 this.simulator = simulator;
81 this.capacity = capacity;
82 }
83
84 /***
85 * Method Resource.
86 *
87 * @param simulator on which is scheduled
88 * @param capacity of the resource
89 */
90 public Resource(final DEVSSimulatorInterface simulator,
91 final double capacity)
92 {
93 this(simulator, "resource", capacity);
94 }
95
96 /***
97 * returns the capacity of the resource
98 *
99 * @return capacity
100 *
101 * @uml.property name="capacity"
102 */
103 public double getCapacity()
104 {
105 return this.capacity;
106 }
107
108
109 /***
110 * Method alterClaimedCapacity.
111 *
112 * @param amount refers the amount which is added to the claimed capacity
113 * @throws RemoteException on network failure
114 */
115 private synchronized void alterClaimedCapacity(final double amount)
116 throws RemoteException
117 {
118 this.claimedCapacity += amount;
119 this.fireEvent(Resource.UTILIZATION_EVENT, this.claimedCapacity,
120 this.simulator.getSimulatorTime());
121 }
122
123 /***
124 * sets the capacity of the resource
125 *
126 * @param capacity the new maximal capacity
127 *
128 * @uml.property name="capacity"
129 */
130 public void setCapacity(final double capacity)
131 {
132 this.capacity = capacity;
133 }
134
135 /***
136 * requests an amount of capacity from the resource \
137 *
138 * @param amount the requested amount
139 * @param requestor the RequestorInterface requesting the amount
140 * @throws RemoteException on network failure
141 * @throws SimRuntimeException on other failures
142 */
143 public synchronized void requestCapacity(final double amount,
144 final ResourceRequestorInterface requestor) throws RemoteException,
145 SimRuntimeException
146 {
147 if (amount < 0.0)
148 {
149 throw new SimRuntimeException(
150 "requested capacity on resource cannot <0.0");
151 }
152 if ((this.claimedCapacity + amount) <= this.capacity)
153 {
154 this.alterClaimedCapacity(amount);
155 this.simulator.scheduleEvent(0, this, requestor,
156 "receiveRequestedResource", new Object[]{
157 new Double(amount), this});
158 } else
159 {
160 synchronized (this.requests)
161 {
162 this.requests.add(new Request(requestor, amount));
163 }
164 this.fireEvent(Resource.RESOURCE_REQUESTED_QUEUE_LENGTH,
165 (double) this.requests.size(), this.simulator
166 .getSimulatorTime());
167 }
168 }
169
170 /***
171 * releases an amount of capacity from the resource.
172 *
173 * @param amount the amount to release
174 * @throws RemoteException on network failure
175 */
176 public void releaseCapacity(final double amount) throws RemoteException
177 {
178 if (amount < 0.0)
179 {
180 throw new IllegalArgumentException(
181 "released capacity on resource cannot <0.0");
182 }
183 this.alterClaimedCapacity(-amount);
184 synchronized (this.requests)
185 {
186 for (Iterator i = this.requests.iterator(); i.hasNext();)
187 {
188 Request request = (Request) i.next();
189 if ((this.capacity - this.claimedCapacity) >= request
190 .getAmount())
191 {
192 this.alterClaimedCapacity(amount);
193 request.getRequestor().receiveRequestedResource(
194 request.getAmount(), this);
195 synchronized (this.requests)
196 {
197 this.requests.remove(request);
198 }
199 this.fireEvent(Resource.RESOURCE_REQUESTED_QUEUE_LENGTH,
200 (double) this.requests.size(), this.simulator
201 .getSimulatorTime());
202 if ((this.capacity - this.claimedCapacity) >= 0.0)
203 {
204 this.releaseCapacity(0);
205 }
206 return;
207 }
208 }
209 }
210 }
211
212 /***
213 * @see java.lang.Object#toString()
214 */
215 public String toString()
216 {
217 return this.description;
218 }
219
220 /***
221 * A Request.
222 */
223 public class Request
224 {
225 /*** requestor the resourceRequestor */
226 private ResourceRequestorInterface requestor;
227
228 /*** amount is the amount requested by the resource */
229 private double amount;
230
231 /***
232 * constructs a new Request
233 *
234 * @param requestor the requestor
235 * @param amount the requested amount
236 */
237 public Request(final ResourceRequestorInterface requestor,
238 final double amount)
239 {
240 this.requestor = requestor;
241 this.amount = amount;
242 }
243
244 /***
245 * gets the requested amount.
246 *
247 * @return the requested amount
248 */
249 public double getAmount()
250 {
251 return this.amount;
252 }
253
254 /***
255 * gets the requestor.
256 *
257 * @return the Requestor.
258 */
259 public ResourceRequestorInterface getRequestor()
260 {
261 return this.requestor;
262 }
263 }
264 }