EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.scheduler.resources.active.special]

COVERAGE SUMMARY FOR SOURCE FILE [SimProcessorSharingResourceWindows.java]

nameclass, %method, %block, %line, %
SimProcessorSharingResourceWindows.java0%   (0/3)0%   (0/28)0%   (0/699)0%   (0/142)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SimProcessorSharingResourceWindows0%   (0/1)0%   (0/24)0%   (0/523)0%   (0/109)
SimProcessorSharingResourceWindows (SchedulerModel, String, String, int): void 0%   (0/1)0%   (0/41)0%   (0/8)
access$0 (SimProcessorSharingResourceWindows): int 0%   (0/1)0%   (0/3)0%   (0/1)
access$1 (SimProcessorSharingResourceWindows): int 0%   (0/1)0%   (0/3)0%   (0/1)
access$2 (SimProcessorSharingResourceWindows): ArrayList 0%   (0/1)0%   (0/3)0%   (0/1)
access$3 (SimProcessorSharingResourceWindows, ISchedulableProcess, double, in... 0%   (0/1)0%   (0/6)0%   (0/1)
access$4 (SimProcessorSharingResourceWindows): void 0%   (0/1)0%   (0/3)0%   (0/1)
access$5 (SimProcessorSharingResourceWindows, ISchedulableProcess): int 0%   (0/1)0%   (0/4)0%   (0/1)
dequeue (ISchedulableProcess): void 0%   (0/1)0%   (0/1)0%   (0/1)
doProcessing (ISchedulableProcess, int, double): void 0%   (0/1)0%   (0/54)0%   (0/13)
enqueue (ISchedulableProcess): void 0%   (0/1)0%   (0/1)0%   (0/1)
getCoreOfARunningProcess (ISchedulableProcess): int 0%   (0/1)0%   (0/26)0%   (0/6)
getCoreWithLongestQueue (): int 0%   (0/1)0%   (0/32)0%   (0/7)
getCoreWithShortestQueue (): int 0%   (0/1)0%   (0/45)0%   (0/10)
getLastCoreProcessWasRunningOn (ISchedulableProcess): int 0%   (0/1)0%   (0/14)0%   (0/3)
getQueueLengthFor (SimResourceInstance): int 0%   (0/1)0%   (0/7)0%   (0/1)
getRemainingDemand (ISchedulableProcess): double 0%   (0/1)0%   (0/51)0%   (0/12)
getSpeed (ISchedulableProcess): double 0%   (0/1)0%   (0/20)0%   (0/3)
putProcessOnCore (ISchedulableProcess, double, int): void 0%   (0/1)0%   (0/28)0%   (0/5)
registerProcess (IRunningProcess): void 0%   (0/1)0%   (0/1)0%   (0/1)
scheduleNextEvent (): void 0%   (0/1)0%   (0/77)0%   (0/14)
start (): void 0%   (0/1)0%   (0/1)0%   (0/1)
stop (): void 0%   (0/1)0%   (0/1)0%   (0/1)
toNow (): void 0%   (0/1)0%   (0/62)0%   (0/10)
updateDemand (ISchedulableProcess, double): void 0%   (0/1)0%   (0/39)0%   (0/7)
     
class SimProcessorSharingResourceWindows$DoLoadBalancingEvent0%   (0/1)0%   (0/2)0%   (0/101)0%   (0/16)
SimProcessorSharingResourceWindows$DoLoadBalancingEvent (SimProcessorSharingR... 0%   (0/1)0%   (0/9)0%   (0/3)
eventRoutine (NullEntity): void 0%   (0/1)0%   (0/92)0%   (0/13)
     
class SimProcessorSharingResourceWindows$ProcessingFinishedEvent0%   (0/1)0%   (0/2)0%   (0/75)0%   (0/17)
SimProcessorSharingResourceWindows$ProcessingFinishedEvent (SimProcessorShari... 0%   (0/1)0%   (0/9)0%   (0/3)
eventRoutine (ISchedulableProcess): void 0%   (0/1)0%   (0/66)0%   (0/14)

1package de.uka.ipd.sdq.scheduler.resources.active.special;
2 
3import java.util.ArrayList;
4import java.util.Hashtable;
5import java.util.Random;
6import java.util.Map.Entry;
7 
8import de.uka.ipd.sdq.probfunction.math.util.MathTools;
9import de.uka.ipd.sdq.scheduler.IRunningProcess;
10import de.uka.ipd.sdq.scheduler.ISchedulableProcess;
11import de.uka.ipd.sdq.scheduler.LoggingWrapper;
12import de.uka.ipd.sdq.scheduler.SchedulerModel;
13import de.uka.ipd.sdq.scheduler.resources.active.AbstractActiveResource;
14import de.uka.ipd.sdq.scheduler.resources.active.SimResourceInstance;
15import de.uka.ipd.sdq.simulation.abstractsimengine.AbstractSimEventDelegator;
16import de.uka.ipd.sdq.simulation.abstractsimengine.IEntity;
17import de.uka.ipd.sdq.simulation.abstractsimengine.NullEntity;
18 
19/**
20 * This class is for testing purposes only. It is used for the MASCOTS paper case study. 
21 * @author hauck
22 *
23 */
24public class SimProcessorSharingResourceWindows extends AbstractActiveResource {
25        
26        private class DoLoadBalancingEvent extends AbstractSimEventDelegator<NullEntity> {
27                
28                public DoLoadBalancingEvent(SchedulerModel model) {
29                        super(model, SimProcessorSharingResourceWindows.class.getName());
30                }
31                
32 
33                @Override
34                 public void eventRoutine(NullEntity who) {
35                        //System.out.println(simulator.time() + ": Trying load balancing...");
36                        int coreToBalanceTo = getCoreWithShortestQueue();
37                        int coreToBalanceFrom = getCoreWithLongestQueue();
38                        if ((running_processesPerCore.get(coreToBalanceTo).size() == 0) && (running_processesPerCore.get(coreToBalanceFrom).size() > 0)) {
39                                // We have an idle core. Do load balancing.
40                                
41                                // select a random process from the sender core
42                                Hashtable<ISchedulableProcess, Double> runningProcesses = running_processesPerCore.get(coreToBalanceFrom);
43                                ISchedulableProcess[] processes = runningProcesses.keySet().toArray(new ISchedulableProcess[]{});
44                        
45                                // move random process from sender core to idle core
46                                Random random = new Random();
47                                ISchedulableProcess processToBalance = processes[random.nextInt(processes.length)];
48                                double simTime = getModel().getSimulationControl().getCurrentSimulationTime();
49                                System.out.println(simTime + ": Balancing process: " + processToBalance.getId() + " from core " + coreToBalanceFrom + " to " + coreToBalanceTo);
50                                Double processValue = runningProcesses.get(processToBalance);
51                                runningProcesses.remove(processToBalance);
52                                putProcessOnCore(processToBalance, processValue, coreToBalanceTo);
53                                
54                        } else {
55                        //        System.out.println(simulator.time() + ": No load balancing needed.");
56                        }
57                        
58                }
59 
60        }
61        
62        private class ProcessingFinishedEvent extends AbstractSimEventDelegator<ISchedulableProcess> {
63                
64                public ProcessingFinishedEvent(SchedulerModel model) {
65                        super(model, ProcessingFinishedEvent.class.getName());
66                }
67 
68                @Override
69                public void eventRoutine(ISchedulableProcess process) {
70                        ISchedulableProcess last = process;
71                        toNow();
72                        // NEW
73                        int core = getCoreOfARunningProcess(last);
74                        running_processesPerCore.get(core).remove(last);
75                        // running_processes.remove(last);
76                        // TODO: now, we have to check, if we have to perform load
77                        // balancing.
78                        // And probably re-calculate times?
79                        
80                        // suggestion:
81                        if (running_processesPerCore.get(core).size() == 0) {
82                                int coreToBalanceFrom = getCoreWithLongestQueue();
83                                if (running_processesPerCore.get(coreToBalanceFrom).size() <= 1) {
84                                        // all cores are idle or have no contention
85                                } else {
86                                        // Try load balancing one time unit from now
87                    DoLoadBalancingEvent event = new DoLoadBalancingEvent(SimProcessorSharingResourceWindows.this
88                            .getModel());
89                                        double simTime = getModel().getSimulationControl().getCurrentSimulationTime();
90                                        event.schedule(IEntity.NULL, simTime+1);
91                                }
92                        }
93                //        System.out.println(simulator.time() + ": " + last.getId() + " finished");
94                        // LoggingWrapper.log(last + " finished.");
95                        scheduleNextEvent();
96                        last.activate();
97                }
98                
99        }
100        
101        private ProcessingFinishedEvent processingFinished = new ProcessingFinishedEvent(null);
102        private ArrayList<Hashtable<ISchedulableProcess,Double>> running_processesPerCore = new ArrayList<Hashtable<ISchedulableProcess, Double>>();
103        // private Hashtable<ISchedulableProcess,Double> running_processes = new
104        // Hashtable<ISchedulableProcess, Double>();
105        private double last_time; 
106        private int coreToUseForInitialLoadBalancing = 0;
107 
108        public SimProcessorSharingResourceWindows(SchedulerModel model, String name, String id, int numberOfCores) {
109                super(model, numberOfCores, name, id);
110                for (int j=0; j<numberOfCores; j++) {
111                        running_processesPerCore.add(new Hashtable<ISchedulableProcess, Double>());
112                }
113        }
114 
115 
116        
117        public void scheduleNextEvent() {
118                /**
119                 * New: look in all queues, i.e. in all nested running_processes
120                 * hashtables, which process is to be scheduled next.
121                 */
122                ISchedulableProcess shortest = null;
123                Double shortestTime = 0.0;
124                for (Hashtable<ISchedulableProcess, Double> running_processes : running_processesPerCore) {
125                        for (ISchedulableProcess process : running_processes.keySet()) {
126                        //        System.out.println("Time: " + simulator.time() + ", looking for shortest time: " + process.getId() + " time: " + running_processes.get(process) + ", speed: " + getSpeed(process));
127                                if (shortest == null || shortestTime > running_processes.get(process) * getSpeed(process)){
128                                        shortest = process;
129                                        shortestTime = running_processes.get(process) * getSpeed(process);
130                                //        System.out.println("Shortest: " + shortest.getId() + ", shortest time: " + shortestTime);
131                                }
132                        }
133                }
134        
135                processingFinished.removeEvent();
136                if (shortest!=null){
137                        // New: calculate time for process
138                        double time = shortestTime;// * getSpeed(shortest);
139                        // double time = running_processes.get(shortest) * getSpeed();
140                //        System.out.println("Time: " + simulator.time() + ", scheduling event at " + time);
141                        if (!MathTools.less(0, time)) {
142                time = 0.0;
143            }
144                        processingFinished.schedule(shortest, time);
145                }
146        }
147        
148        private int getCoreOfARunningProcess(ISchedulableProcess process) {
149                for (int i=0; i<running_processesPerCore.size(); i++) {
150                        Hashtable<ISchedulableProcess, Double> running_processes = running_processesPerCore.get(i);
151                        if (running_processes.containsKey(process)) {
152                                return i;
153                        }
154                }
155                LoggingWrapper.logger.warn("Core of process not found. Returning core 0.");
156                return 0;
157        }
158        
159        private int getCoreWithLongestQueue() {
160                int coreWithLongestQueue = 0;
161                int queueSize = 0;
162                for (int i=0; i<running_processesPerCore.size(); i++) {
163                        if (running_processesPerCore.get(i).size() > queueSize) {
164                                queueSize = running_processesPerCore.get(i).size();
165                                coreWithLongestQueue = i;
166                        }
167                }
168                return coreWithLongestQueue;
169        }
170        
171        private int getCoreWithShortestQueue() {
172                int coreWithShortestQueue = -1;
173                int queueSize = 0;
174                for (int i=0; i<running_processesPerCore.size(); i++) {
175                        if (coreWithShortestQueue == -1) {
176                                queueSize = running_processesPerCore.get(i).size();
177                                coreWithShortestQueue = i;
178                        } else {
179                                if (running_processesPerCore.get(i).size() < queueSize) {
180                                        queueSize = running_processesPerCore.get(i).size();
181                                        coreWithShortestQueue = i;
182                                }
183                        }
184                }
185                return coreWithShortestQueue;
186        }
187 
188 
189        private void toNow() {
190                double now = getModel().getSimulationControl().getCurrentSimulationTime();
191                double passed_time = now - last_time;
192                // System.out.println("toNow: " + now + " - " + last_time + " = " +
193                // passed_time);
194                if (MathTools.less(0, passed_time)){
195                        // passed_time /= getSpeed();
196                        // NEW
197                        for (Hashtable<ISchedulableProcess, Double> running_processes : running_processesPerCore) {
198                                for (Entry<ISchedulableProcess,Double> e : running_processes.entrySet()) {
199                                        double processPassedTime = passed_time / getSpeed(e.getKey());
200                                        double rem =   e.getValue() - processPassedTime;
201                                        // System.out.println("toNow " + e.getKey().getId() + ": " +
202                                        // e.getValue() + " - " + processPassedTime + " = " + rem);
203                                        e.setValue(rem);
204                                }
205                        }
206                }
207                last_time = now;
208        }
209        
210        @Override
211        public double getRemainingDemand(ISchedulableProcess process) {
212                boolean hasDemand = false;
213                for (Hashtable<ISchedulableProcess, Double> running_processes : running_processesPerCore) {
214                        if (running_processes.containsKey(process)) {
215                                hasDemand = true;
216                                break;
217                        }
218                }
219                if (hasDemand == false) {
220                        return 0.0;
221                }
222                toNow();
223                for (Hashtable<ISchedulableProcess, Double> running_processes : running_processesPerCore) {
224                        if (!running_processes.contains(process)) {
225                                return running_processes.get(process);
226                        }
227                }
228                // Should not be reached.
229                return 0.0;
230        }
231        
232        @Override
233        public void updateDemand(ISchedulableProcess process, double demand) {
234                for (Hashtable<ISchedulableProcess, Double> running_processes : running_processesPerCore) {
235                        for (Entry<ISchedulableProcess,Double> e : running_processes.entrySet()) {
236                                if (e.getKey().equals(process)) {
237                                        e.setValue(demand);
238                                        break;
239                                }
240                        }
241                }
242                scheduleNextEvent();
243        }
244 
245    // New: calculate speed for a process.
246        private double getSpeed(ISchedulableProcess process) {
247                int core = getCoreOfARunningProcess(process);
248                double speed = (double)running_processesPerCore.get(core).size();
249                // double speed = (double)running_processes.size() /
250                // (double)getCapacity();
251                
252                // comparison here is unnecessary, speed cannot be lower than 1. Keep it
253                // anyway.
254                return speed < 1.0 ? 1.0 : speed;
255        }
256 
257 
258        public void start() {
259        }
260 
261 
262        @Override
263        protected void dequeue(ISchedulableProcess process) {
264        }
265 
266 
267        @Override
268        protected void doProcessing(ISchedulableProcess process, int resourceServiceID, double demand) {
269                toNow();
270                LoggingWrapper.log("PS: " + process + " demands " + demand);
271                //System.out.println("PS: " + process.getId() + " demands " + demand);
272                int coreToPutOn = getLastCoreProcessWasRunningOn(process);
273                if (coreToPutOn == -1) {
274                        // This is a new process which has issued demand for the first time.
275                        // New: Select core for initial load balancing based on cyclic
276                        // splitting
277                        putProcessOnCore(process, demand, coreToUseForInitialLoadBalancing);
278                        // running_processes.put(process, demand);
279                        coreToUseForInitialLoadBalancing++;
280                        if (coreToUseForInitialLoadBalancing>=getCapacity()) {
281                                // start with first core again next time
282                                coreToUseForInitialLoadBalancing = 0;
283                        }
284                } else {
285                        putProcessOnCore(process, demand, coreToPutOn);
286                        // running_processesPerCore.get(coreToPutOn).put(process, demand);
287                }
288                
289                // I don't know if this is right here.
290                // I call toNow() again to update all processes (some processes might
291                // now share the core with the new process)
292                toNow();
293                scheduleNextEvent();
294                process.passivate();
295        }
296 
297        @Override
298        protected void enqueue(ISchedulableProcess process) {
299        }
300 
301 
302        public void stop() {
303                
304        }
305 
306        public void registerProcess(IRunningProcess runningProcess) {
307        }
308        
309        public int getQueueLengthFor(SimResourceInstance simResourceInstance) {
310                // TODO where is this needed? Return hard coded queue length of first
311                // core.
312                return this.running_processesPerCore.get(0).size();
313                // return this.running_processes.size();
314        }
315        
316        private Hashtable<ISchedulableProcess,Integer> all_processes = new Hashtable<ISchedulableProcess, Integer>();
317        
318        /**
319         * return -1 if a process was not running before, i.e. is a new process.
320         * 
321         * @param process
322         * @return
323         */
324        private int getLastCoreProcessWasRunningOn(ISchedulableProcess process) {
325                if (all_processes.containsKey(process)) {
326                        return all_processes.get(process);
327                }
328                return -1;
329        }
330        
331        private void putProcessOnCore(ISchedulableProcess process, double demand, int core) {
332                if (all_processes.containsKey(process)) {
333                        all_processes.remove(process);
334                }
335                all_processes.put(process, core);
336                //System.out.println(simulator.time() + ": Putting " + process.getId() + " with demand " + demand + " on core " + core);
337                running_processesPerCore.get(core).put(process, demand); 
338        }
339 
340}

[all classes][de.uka.ipd.sdq.scheduler.resources.active.special]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov