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