View Javadoc

    1   /*
    2    * @(#)Resource.java Feb 1, 2003
    3    *
    4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
    5    * the Netherlands All rights reserved.
    6    *
    7    * This software is proprietary information of Delft University of Technology
    8    * The code is published under the General Public License
    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 }