1 | /** |
2 | * |
3 | */ |
4 | package de.uka.ipd.sdq.simucomframework.resources; |
5 | |
6 | import scheduler.SchedulerLibrary; |
7 | import scheduler.configuration.ConfigurationFactory; |
8 | import scheduler.configuration.PriorityClass; |
9 | import scheduler.configuration.ProcessConfiguration; |
10 | import scheduler.configuration.SchedulerConfiguration; |
11 | import de.uka.ipd.sdq.scheduler.IActiveResource; |
12 | import de.uka.ipd.sdq.scheduler.ISchedulableProcess; |
13 | import de.uka.ipd.sdq.scheduler.processes.impl.ProcessWithPriority; |
14 | import de.uka.ipd.sdq.scheduler.tools.SchedulerTools; |
15 | import de.uka.ipd.sdq.simucomframework.Context; |
16 | import de.uka.ipd.sdq.simucomframework.SimuComSimProcess; |
17 | import de.uka.ipd.sdq.simucomframework.model.SimuComModel; |
18 | |
19 | /** |
20 | * @author Snowball |
21 | * |
22 | */ |
23 | public class ScheduledResource extends AbstractScheduledResource { |
24 | |
25 | private static final String PATHMAP_TO_SCHEDULER_LIBRARY = "pathmap://PCM_MODELS/Library.scheduler"; |
26 | private static long resourceId = 1; |
27 | private String processingRate = "0"; |
28 | |
29 | private double totalDemandedTime; |
30 | |
31 | public ScheduledResource( |
32 | SimuComModel myModel, |
33 | String typeID, |
34 | String resourceContainerID, |
35 | String resourceTypeID, |
36 | String description, |
37 | String processingRate, |
38 | Double mttf, |
39 | Double mttr, |
40 | SchedulingStrategy strategy, |
41 | int numberOfCores, |
42 | boolean requiredByContainer) { |
43 | super(myModel, typeID, resourceContainerID, resourceTypeID, |
44 | description, strategy, numberOfCores, |
45 | requiredByContainer); |
46 | this.processingRate = processingRate; |
47 | |
48 | // Reliability Stuff. |
49 | this.mttf = mttf; |
50 | this.mttr = mttr; |
51 | this.canBeUnavailable = (myModel.getConfiguration().getSimulateFailures() |
52 | && (this.mttf > 0.0) && (this.mttr > 0.0)); |
53 | |
54 | // used to let resource fail and be repaired again: |
55 | if (this.canBeUnavailable) { |
56 | createAvailabilityEvents(myModel); |
57 | } |
58 | } |
59 | |
60 | @Override |
61 | protected IActiveResource createActiveResource(SimuComModel myModel) { |
62 | logger.debug("Creating scheduled resource with strategy " |
63 | + this.schedulingStrategy.name() + " and " |
64 | + this.numberOfInstances + " replicas!"); |
65 | IActiveResource aResource = getScheduledResource(myModel, |
66 | this.schedulingStrategy, this.numberOfInstances, |
67 | "Utilisation of " + this.getName() + " " + this.description); |
68 | return aResource; |
69 | } |
70 | |
71 | /* Loads scheduler configuration */ |
72 | private IActiveResource getResource(String schedulerLibFileName, |
73 | String schedulerName, int numReplicas, String sensorDescription) { |
74 | |
75 | SchedulerLibrary lib = (SchedulerLibrary) SchedulerTools |
76 | .loadFromXMI(schedulerLibFileName); |
77 | SchedulerConfiguration selectedConf = null; |
78 | for (SchedulerConfiguration conf : lib.getSchedulerConfiguration()) { |
79 | if (conf.getName().equals(schedulerName)) { |
80 | selectedConf = conf; |
81 | break; |
82 | } |
83 | } |
84 | if (selectedConf != null) { |
85 | resourceConf = ConfigurationFactory.eINSTANCE |
86 | .createActiveResourceConfiguration(); |
87 | resourceConf.setName(schedulerName); |
88 | resourceConf.setReplicas(numReplicas); |
89 | resourceConf.setSchedulerConfiguration(selectedConf); |
90 | IActiveResource resource = getModel().getSchedulingFactory() |
91 | .createActiveResource(resourceConf); |
92 | return resource; |
93 | } |
94 | return null; |
95 | } |
96 | |
97 | private IActiveResource getScheduledResource(SimuComModel simuComModel, SchedulingStrategy strategy, |
98 | int numberOfCores, String sensorDescription) { |
99 | IActiveResource scheduledResource = null; |
100 | |
101 | switch (strategy) { |
102 | |
103 | // active resources scheduled by standard scheduling techniques |
104 | case FCFS: |
105 | scheduledResource = getModel().getSchedulingFactory() |
106 | .createSimFCFSResource(SchedulingStrategy.FCFS.toString(), |
107 | getNextResourceId()); |
108 | break; |
109 | case PROCESSOR_SHARING: |
110 | scheduledResource = getModel().getSchedulingFactory() |
111 | .createSimProcessorSharingResource( |
112 | SchedulingStrategy.PROCESSOR_SHARING.toString(), |
113 | getNextResourceId(), numberOfCores); |
114 | break; |
115 | case DELAY: |
116 | scheduledResource = getModel().getSchedulingFactory() |
117 | .createSimDelayResource( |
118 | SchedulingStrategy.DELAY.toString(), |
119 | getNextResourceId()); |
120 | break; |
121 | // active resources scheduled by improved scheduler |
122 | case LINUX_2_6_O1: |
123 | scheduledResource = getResource(PATHMAP_TO_SCHEDULER_LIBRARY, |
124 | "Linux 2.6.22", numberOfCores, sensorDescription); |
125 | break; |
126 | case LINUX_2_6_CFS: |
127 | scheduledResource = getModel().getSchedulingFactory() |
128 | .createSimProcessorSharingResource( |
129 | SchedulingStrategy.LINUX_2_6_CFS.toString(), |
130 | getNextResourceId(), numberOfCores); |
131 | break; |
132 | case WINDOWS_7: |
133 | // Windows 7, Windows Vista and Windows Server 2003 share the same |
134 | // scheduler |
135 | case WINDOWS_VISTA: |
136 | case WINDOWS_SERVER_2003: |
137 | scheduledResource = getResource(PATHMAP_TO_SCHEDULER_LIBRARY, |
138 | "Windows 2003", numberOfCores, sensorDescription); |
139 | break; |
140 | case WINDOWS_XP: |
141 | scheduledResource = getResource(PATHMAP_TO_SCHEDULER_LIBRARY, |
142 | "Windows XP", numberOfCores, sensorDescription); |
143 | break; |
144 | case SPECIAL_WINDOWS: |
145 | scheduledResource = getModel().getSchedulingFactory() |
146 | .createSimProcessorSharingResourceWindows( |
147 | SchedulingStrategy.SPECIAL_WINDOWS.toString(), |
148 | getNextResourceId(), numberOfCores); |
149 | break; |
150 | case SPECIAL_LINUXO1: |
151 | scheduledResource = getModel().getSchedulingFactory() |
152 | .createSimProcessorSharingResourceLinuxO1( |
153 | SchedulingStrategy.SPECIAL_LINUXO1.toString(), |
154 | getNextResourceId(), numberOfCores); |
155 | break; |
156 | case GINPEX_DISK: |
157 | scheduledResource = getModel().getSchedulingFactory().createResourceFromExtension( |
158 | "de.uka.ipd.sdq.simucom.ginpex.scheduler.hdd", SchedulingStrategy.GINPEX_DISK.toString(), |
159 | getNextResourceId()); |
160 | //scheduledResource = ISchedulingFactory.eINSTANCE |
161 | // .createSimGinpexDiskResource( |
162 | // SchedulingStrategy.GINPEX_DISK.toString(), |
163 | // getNextResourceId(), getModel().getConfig().getHddParameterConfig()); |
164 | break; |
165 | } |
166 | |
167 | if (scheduledResource instanceof SimuComExtensionResource) { |
168 | // The resource takes additional configuration that is available in the SimuComModel object |
169 | // As the scheduler project is currently SimuCom-agnostic, we use the SimuComExtensionResource class |
170 | // to initialize the resource wit a SimuCom-related object. |
171 | ((SimuComExtensionResource)scheduledResource).initialize(simuComModel); |
172 | } |
173 | |
174 | return scheduledResource; |
175 | } |
176 | |
177 | private void registerProcessWindows(ISchedulableProcess process, |
178 | IActiveResource resource) { |
179 | if (resourceConf != null) { |
180 | ProcessConfiguration processConf = ConfigurationFactory.eINSTANCE |
181 | .createProcessConfiguration(); |
182 | processConf.setName(process.getId()); |
183 | processConf.setPriority(PriorityClass.DEFAULT); |
184 | processConf.setReplicas(1); |
185 | ProcessWithPriority p = (ProcessWithPriority) getModel().getSchedulingFactory() |
186 | .createRunningProcess(process, processConf, resourceConf); |
187 | |
188 | resource.registerProcess(p); |
189 | } |
190 | } |
191 | |
192 | @Override |
193 | protected double calculateDemand(double demand) { |
194 | return demand |
195 | / (Double) Context.evaluateStatic(processingRate, Double.class); |
196 | } |
197 | |
198 | @Override |
199 | public void activateResource() { |
200 | aResource.start(); |
201 | super.activateResource(); |
202 | } |
203 | |
204 | @Override |
205 | public void consumeResource(SimuComSimProcess process, int resourceServiceID, double abstractDemand) { |
206 | // Check first if the resource is currently available. |
207 | // This works for the standard resource types (CPU, HDD, DELAY). |
208 | assertAvailability(); |
209 | |
210 | registerProcessWindows(process, aResource); |
211 | double concreteDemand = calculateDemand(abstractDemand); |
212 | fireDemand(concreteDemand); |
213 | this.totalDemandedTime += concreteDemand; |
214 | aResource.process(process, resourceServiceID, concreteDemand); |
215 | } |
216 | |
217 | @Override |
218 | public double getRemainingDemandForProcess(SimuComSimProcess thread) { |
219 | return aResource.getRemainingDemand(thread); |
220 | } |
221 | |
222 | @Override |
223 | public void updateDemand(SimuComSimProcess thread, double demand) { |
224 | aResource.updateDemand(thread, demand); |
225 | } |
226 | |
227 | @Override |
228 | public void deactivateResource() { |
229 | // calculate overall utilization and inform listeners |
230 | double totalTime = getModel().getSimulationControl() |
231 | .getCurrentSimulationTime() |
232 | * this.numberOfInstances; |
233 | if (totalDemandedTime > totalTime) { |
234 | totalDemandedTime = totalTime; |
235 | } |
236 | fireOverallUtilization(totalDemandedTime, totalTime); |
237 | |
238 | aResource.stop(); |
239 | } |
240 | |
241 | public static String getNextResourceId() { |
242 | return Long.toString(resourceId++); |
243 | } |
244 | |
245 | @Override |
246 | public IActiveResource getScheduledResource() { |
247 | return aResource; |
248 | } |
249 | |
250 | } |