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 | } |