| 1 | package de.uka.ipd.sdq.simucomframework.resources; |
| 2 | |
| 3 | import java.util.ArrayList; |
| 4 | import java.util.List; |
| 5 | |
| 6 | import de.uka.ipd.sdq.scheduler.IActiveResource; |
| 7 | import de.uka.ipd.sdq.scheduler.IPassiveResource; |
| 8 | import de.uka.ipd.sdq.scheduler.priority.IPriorityBoost; |
| 9 | import de.uka.ipd.sdq.scheduler.priority.IPriorityUpdateStrategy; |
| 10 | import de.uka.ipd.sdq.scheduler.priority.boost.StaticPriorityBoost; |
| 11 | import de.uka.ipd.sdq.scheduler.priority.update.DecayToBaseUpdate; |
| 12 | import de.uka.ipd.sdq.scheduler.resources.active.SimActiveResource; |
| 13 | import de.uka.ipd.sdq.scheduler.resources.passive.SimFairPassiveResource; |
| 14 | import de.uka.ipd.sdq.scheduler.resources.passive.SimUnfairPassiveResource; |
| 15 | import de.uka.ipd.sdq.simucomframework.SimuComSimProcess; |
| 16 | import de.uka.ipd.sdq.simucomframework.exceptions.ResourceContainerIsMissingRequiredResourceType; |
| 17 | import de.uka.ipd.sdq.simucomframework.model.SimuComModel; |
| 18 | |
| 19 | public class SimulatedResourceContainer extends |
| 20 | AbstractSimulatedResourceContainer { |
| 21 | |
| 22 | private SchedulingStrategy operatingSystem; |
| 23 | private AbstractScheduledResource managingResource = null; |
| 24 | protected SimulatedResourceContainer parentResourceContainer = null; |
| 25 | protected List<SimulatedResourceContainer> nestedResourceContainers = null; |
| 26 | |
| 27 | public SimulatedResourceContainer(SimuComModel myModel, String containerID) { |
| 28 | super(myModel, containerID); |
| 29 | nestedResourceContainers = new ArrayList<SimulatedResourceContainer>(); |
| 30 | } |
| 31 | |
| 32 | public IPassiveResource createPassiveResource(String name, |
| 33 | String passiveResourceID, String assemblyContextID, |
| 34 | String combinedID, int capacity) { |
| 35 | IPassiveResource r = null; |
| 36 | if (managingResource == null) { |
| 37 | r = getSimplePassiveResource(name, passiveResourceID, |
| 38 | assemblyContextID, combinedID, capacity); |
| 39 | } else { |
| 40 | switch (operatingSystem) { |
| 41 | case WINDOWS_SERVER_2003: |
| 42 | case WINDOWS_XP: |
| 43 | case WINDOWS_VISTA: |
| 44 | case WINDOWS_7: |
| 45 | r = getPassiveResourceWindows(name, passiveResourceID, |
| 46 | capacity, 1, true, true, managingResource |
| 47 | .getScheduledResource()); |
| 48 | break; |
| 49 | case LINUX_2_6_O1: |
| 50 | r = getPassiveResourceLinux(name, passiveResourceID, capacity, |
| 51 | true, managingResource.getScheduledResource()); |
| 52 | break; |
| 53 | case LINUX_2_6_CFS: |
| 54 | // Use the same passive resource as for a processor sharing scheduler. |
| 55 | r = getSimplePassiveResource(name, passiveResourceID, |
| 56 | assemblyContextID, combinedID, capacity); |
| 57 | break; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | // setup calculators |
| 62 | CalculatorHelper.setupStateCalculator(r, this.myModel); |
| 63 | CalculatorHelper.setupWaitingTimeCalculator(r, this.myModel); |
| 64 | CalculatorHelper.setupHoldTimeCalculator(r, this.myModel); |
| 65 | |
| 66 | return r; |
| 67 | } |
| 68 | |
| 69 | public List<SimulatedResourceContainer> getNestedResourceContainers() { |
| 70 | return nestedResourceContainers; |
| 71 | } |
| 72 | |
| 73 | public SimulatedResourceContainer getParentResourceContainer() { |
| 74 | return parentResourceContainer; |
| 75 | } |
| 76 | |
| 77 | public void addNestedResourceContainer(String nestedResourceContainerId) { |
| 78 | AbstractSimulatedResourceContainer resourceContainer = myModel.getResourceRegistry().getResourceContainer(nestedResourceContainerId); |
| 79 | if ((resourceContainer == null) || (!(resourceContainer instanceof SimulatedResourceContainer))) { |
| 80 | throw new RuntimeException( |
| 81 | "Could not initialize resouce container " + this.myContainerID + ": Nested resource container " + nestedResourceContainerId + " is not available."); |
| 82 | } |
| 83 | nestedResourceContainers.add((SimulatedResourceContainer)resourceContainer); |
| 84 | } |
| 85 | |
| 86 | public void setParentResourceContainer(String parentResourceContainerId) { |
| 87 | AbstractSimulatedResourceContainer resourceContainer = myModel.getResourceRegistry().getResourceContainer(parentResourceContainerId); |
| 88 | if ((resourceContainer == null) || (!(resourceContainer instanceof SimulatedResourceContainer))) { |
| 89 | throw new RuntimeException( |
| 90 | "Could not initialize resouce container " + this.myContainerID + ": Parent resource container " + parentResourceContainerId + " is not available."); |
| 91 | } |
| 92 | parentResourceContainer = (SimulatedResourceContainer)resourceContainer; |
| 93 | } |
| 94 | |
| 95 | public void addActiveResource( |
| 96 | String typeID, |
| 97 | String[] providedInterfaceIds, |
| 98 | String resourceContainerID, |
| 99 | String resourceTypeID, |
| 100 | String description, |
| 101 | String processingRate, |
| 102 | Double mttf, |
| 103 | Double mttr, |
| 104 | String units, |
| 105 | SchedulingStrategy strategy, |
| 106 | int numberOfReplicas, |
| 107 | boolean requiredByContainer){ |
| 108 | ScheduledResource r = new ScheduledResource( |
| 109 | myModel, |
| 110 | typeID, |
| 111 | resourceContainerID, |
| 112 | resourceTypeID, |
| 113 | description, |
| 114 | processingRate, |
| 115 | mttf, |
| 116 | mttr, |
| 117 | strategy, |
| 118 | numberOfReplicas, |
| 119 | requiredByContainer); |
| 120 | activeResources.put(typeID, r); |
| 121 | |
| 122 | // Currently, resources can also be looked up by the provided interface id |
| 123 | if (providedInterfaceIds != null) { |
| 124 | for (String providedInterfaceId : providedInterfaceIds) { |
| 125 | activeResourceProvidedInterfaces.put(providedInterfaceId, typeID); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | if (SchedulingStrategyHelper.isExactSchedulingStrategy(strategy)) { |
| 130 | assert this.managingResource == null; |
| 131 | this.operatingSystem = strategy; |
| 132 | this.managingResource = activeResources.get(typeID); |
| 133 | } |
| 134 | |
| 135 | // setup calculators |
| 136 | // TODO: setup waiting time calculator |
| 137 | // CalculatorHelper.setupWaitingTimeCalculator(r); |
| 138 | CalculatorHelper.setupDemandCalculator(r, this.myModel); |
| 139 | |
| 140 | // setup utilization calculators depending on their scheduling strategy |
| 141 | // and number of cores |
| 142 | if (strategy.equals(SchedulingStrategy.PROCESSOR_SHARING)) { |
| 143 | if (r.getNumberOfInstances() == 1) { |
| 144 | CalculatorHelper.setupStateCalculator(r, this.myModel); |
| 145 | } else { |
| 146 | CalculatorHelper.setupOverallUtilizationCalculator(r, this.myModel); |
| 147 | } |
| 148 | } else if (strategy.equals(SchedulingStrategy.DELAY) |
| 149 | || strategy.equals(SchedulingStrategy.FCFS)) { |
| 150 | assert (r.getNumberOfInstances() == 1) : "DELAY and FCFS resources are expected to " |
| 151 | + "have exactly one core"; |
| 152 | CalculatorHelper.setupStateCalculator(r, this.myModel); |
| 153 | } else if (strategy.equals(SchedulingStrategy.GINPEX_DISK)) { |
| 154 | CalculatorHelper.setupOverallUtilizationCalculator(r, this.myModel); |
| 155 | } else if (SchedulingStrategyHelper.isExactSchedulingStrategy(strategy)) { |
| 156 | CalculatorHelper.setupOverallUtilizationCalculator(r, this.myModel); |
| 157 | } else { |
| 158 | throw new RuntimeException( |
| 159 | "Could not setup utilization calculator at resource " |
| 160 | + description |
| 161 | + " as it is unknown how to handle the scheduling strategy " |
| 162 | + strategy.name() + "."); |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | private IPassiveResource getPassiveResourceWindows(String name, String id, |
| 167 | int capacity, int bonus, boolean resetTimeSlice, boolean isFair, |
| 168 | IActiveResource managingResource) { |
| 169 | IPriorityUpdateStrategy update = new DecayToBaseUpdate(); |
| 170 | IPriorityBoost boost = new StaticPriorityBoost(update, bonus, 0, |
| 171 | resetTimeSlice); |
| 172 | |
| 173 | if (isFair) { |
| 174 | return new SimFairPassiveResource(myModel, capacity, name, id, boost, |
| 175 | (SimActiveResource) managingResource); |
| 176 | } else { |
| 177 | return new SimUnfairPassiveResource(myModel, capacity, name, id, boost, |
| 178 | (SimActiveResource) managingResource, 0.1, true); |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | private IPassiveResource getPassiveResourceLinux(String name, String id, |
| 183 | int capacity, boolean isFair, IActiveResource managingResource) { |
| 184 | if (isFair) { |
| 185 | return new SimFairPassiveResource(myModel, capacity, name, id, null, |
| 186 | (SimActiveResource) managingResource); |
| 187 | } else { |
| 188 | return new SimUnfairPassiveResource(myModel, capacity, name, id, null, |
| 189 | (SimActiveResource) managingResource, 0.1, true); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | private IPassiveResource getSimplePassiveResource(String name, |
| 194 | String passiveResourceID, String assemblyContextID, |
| 195 | String combinedID, int capacity) { |
| 196 | // return new SimFairPassiveResource(capacity, name, name, null,null); |
| 197 | return new SimSimpleFairPassiveResource(myModel, capacity, name, passiveResourceID, |
| 198 | assemblyContextID, combinedID, myModel.getConfiguration().getSimulateFailures()); |
| 199 | } |
| 200 | |
| 201 | /** |
| 202 | * Demand processing of a resource demand by a given type of active resources. |
| 203 | * If the resource container has no own resources, look in parent resource container. |
| 204 | * @param requestingProcess The thread requesting the processing of a resouce demand |
| 205 | * @param typeID ID of the resource type to which the demand is directed. Same as the |
| 206 | * PCM resource type IDs |
| 207 | * @param demand The demand in units processable by the resource. The resource is |
| 208 | * responsible itself for converting this demand into time spans |
| 209 | */ |
| 210 | public void loadActiveResource(SimuComSimProcess requestingProcess, String typeID, double demand) { |
| 211 | try { |
| 212 | super.loadActiveResource(requestingProcess, typeID, demand); |
| 213 | } catch (ResourceContainerIsMissingRequiredResourceType e) { |
| 214 | if (parentResourceContainer == null) { |
| 215 | logger.error("Resource container is missing a resource which was attempted to be loaded"+ |
| 216 | " by a component and has no parent Resource Container to look in. ID of resource type was: "+typeID); |
| 217 | throw new ResourceContainerIsMissingRequiredResourceType(typeID); |
| 218 | } else { |
| 219 | parentResourceContainer.loadActiveResource(requestingProcess, typeID, demand); |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | /** |
| 225 | * Demand processing of a resource demand by a given type of active resource and a resource interface operation. |
| 226 | * If the resource container has no own resources, look in parent resource container. |
| 227 | * @param requestingProcess The thread requesting the processing of a resource demand |
| 228 | * @param typeID ID of the resource provided interface to which the demand is directed. |
| 229 | * @param resourceServiceID the id of the resource service to be called. |
| 230 | * @param demand The demand in units processable by the resource. The resource is |
| 231 | * responsible itself for converting this demand into time spans |
| 232 | */ |
| 233 | public void loadActiveResource(SimuComSimProcess requestingProcess, String providedInterfaceID, int resourceServiceID, double demand) { |
| 234 | try { |
| 235 | super.loadActiveResource(requestingProcess, providedInterfaceID, resourceServiceID, demand); |
| 236 | } catch (ResourceContainerIsMissingRequiredResourceType e) { |
| 237 | if (parentResourceContainer == null) { |
| 238 | logger.error("Resource container is missing a resource which was attempted to be loaded"+ |
| 239 | " by a component and has no parent Resource Container to look in. ID of resource type was: "+e.getTypeID()); |
| 240 | throw new ResourceContainerIsMissingRequiredResourceType(e.getTypeID()); |
| 241 | } else { |
| 242 | parentResourceContainer.loadActiveResource(requestingProcess, providedInterfaceID, resourceServiceID, demand); |
| 243 | } |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | |
| 248 | public AbstractScheduledResource getResourceInResourceContainerOrParentResourceContainer(String resourceTypeID) { |
| 249 | AbstractScheduledResource resource = activeResources.get(resourceTypeID); |
| 250 | if (resource == null) { |
| 251 | if (parentResourceContainer != null) { |
| 252 | return parentResourceContainer.getResourceInResourceContainerOrParentResourceContainer(resourceTypeID); |
| 253 | } |
| 254 | } |
| 255 | return resource; |
| 256 | } |
| 257 | |
| 258 | } |