1 package Analysis.Scheduling;
3 import java.util.Hashtable;
4 import java.util.Iterator;
5 import java.util.LinkedList;
6 import java.util.Queue;
7 import java.util.Vector;
8 import java.util.Map.Entry;
10 import Analysis.TaskStateAnalysis.FlagState;
11 import Analysis.TaskStateAnalysis.TaskAnalysis;
12 import IR.ClassDescriptor;
14 import IR.TaskDescriptor;
17 public class ScheduleSimulator {
19 private Vector<Schedule> scheduling;
20 private Vector<CoreSimulator> cores;
21 private Vector<TaskSimulator> tasks;
22 private Vector<CheckPoint> checkpoints;
23 private int processTime;
24 private int invoketime;
27 TaskAnalysis taskanalysis;
29 public ScheduleSimulator(int coreNum, State state, TaskAnalysis taskanalysis) {
31 this.coreNum = coreNum;
32 this.scheduling = null;
35 this.checkpoints = null;
39 this.taskanalysis = taskanalysis;
42 public ScheduleSimulator(int coreNum, Vector<Schedule> scheduling, State state, TaskAnalysis taskanalysis) {
44 this.coreNum = coreNum;
45 this.scheduling = scheduling;
46 this.cores = new Vector<CoreSimulator>(this.coreNum);
47 for(int i = 0; i < this.coreNum; i++) {
48 this.cores.add(new CoreSimulator(FIFORSchedule.getFIFORSchedule(), i));
50 this.tasks = new Vector<TaskSimulator>();
51 this.checkpoints = null;
55 this.taskanalysis = taskanalysis;
59 public Vector<CheckPoint> getCheckpoints() {
63 public int getCoreNum() {
67 public void setCoreNum(int coreNum) {
68 this.coreNum = coreNum;
69 if(this.cores != null) {
72 this.cores = new Vector<CoreSimulator>(this.coreNum);
73 for(int i = 0; i < this.coreNum; i++) {
74 this.cores.add(new CoreSimulator(FIFORSchedule.getFIFORSchedule(), i));
76 if(this.scheduling != null) {
81 public int getUtility(int index) {
82 return (this.cores.elementAt(index).getActiveTime() * 100) / this.processTime;
85 public Vector<Schedule> getScheduling() {
89 public void setScheduling(Vector<Schedule> scheduling) {
90 this.scheduling = scheduling;
91 if(this.tasks == null) {
92 this.tasks = new Vector<TaskSimulator>();
96 if(this.cores != null) {
97 for(int i = 0; i < this.coreNum; i++) {
98 CoreSimulator core = this.cores.elementAt(i);
100 core.setRSchedule(FIFORSchedule.getFIFORSchedule());
103 this.cores = new Vector<CoreSimulator>(this.coreNum);
104 for(int i = 0; i < this.coreNum; i++) {
105 this.cores.add(new CoreSimulator(FIFORSchedule.getFIFORSchedule(), i));
112 public void applyScheduling() {
113 assert(this.state != null);
115 for(int i = 0; i < this.scheduling.size(); i++) {
116 Schedule temp = this.scheduling.elementAt(i);
117 CoreSimulator cs = this.cores.elementAt(temp.getCoreNum());
118 cs.deployTasks(temp.getTasks());
119 cs.setTargetCSimulator(temp.getTargetCoreTable());
120 cs.setTargetFState(temp.getTargetFStateTable());
122 // inject a Startup Object to each core
123 for(int i = 0; i < this.coreNum; i++) {
124 ClassDescriptor startupobject=(ClassDescriptor)state.getClassSymbolTable().get(TypeUtil.StartupClass);
125 FlagState fsstartup = (FlagState)taskanalysis.getRootNodes(startupobject).elementAt(0);
126 ObjectSimulator newObj = new ObjectSimulator(startupobject, fsstartup);
127 this.cores.elementAt(i).addObject(newObj);
131 public Vector<TaskSimulator> getTasks() {
135 public int process() {
136 assert(this.scheduling != null);
140 if(this.checkpoints == null) {
141 this.checkpoints = new Vector<CheckPoint>();
143 this.checkpoints.clear();
146 this.processTime = 0;
148 // first decide next task to execute on each core
150 for(i = 0; i < this.cores.size(); i++) {
151 CoreSimulator cs = this.cores.elementAt(i);
152 TaskSimulator task = cs.process();
154 this.tasks.add(task);
158 // add STARTTASK checkpoint for all the initial tasks
159 CheckPoint cp = new CheckPoint(this.processTime);
160 for(i = 0; i < this.tasks.size(); i++) {
161 TaskSimulator task = this.tasks.elementAt(i);
162 Action action = new Action(task.getCs().getCoreNum(), Action.TASKSTART);
163 action.setTd(task.getTd());
164 cp.addAction(action);
166 this.checkpoints.add(cp);
169 // if no more tasks on each core, simulation finish
170 if(this.tasks.size() == 0) {
174 // for each task in todo queue, decide the execution path of this time
175 // according to statistic information
176 //int index = 0; // indicate the task to finish first
177 int finishTime = Integer.MAX_VALUE;
178 Vector<TaskSimulator> finishTasks = new Vector<TaskSimulator>();
179 for(i = 0; i < this.tasks.size(); i++) {
180 TaskSimulator task = this.tasks.elementAt(i);
182 int tempTime = task.getCurrentRun().getFinishTime();
183 if(tempTime < finishTime) {
184 finishTime = tempTime;
186 finishTasks.add(task);
187 } else if (tempTime == finishTime) {
188 finishTasks.add(task);
191 for(i = 0; i < this.tasks.size(); i++) {
192 TaskSimulator task = this.tasks.elementAt(i);
193 if(!finishTasks.contains(task)) {
194 task.getCs().updateTask(finishTime);
197 this.processTime += finishTime;
198 cp = new CheckPoint(this.processTime);
199 Action action = null;
200 for(i = 0; i < finishTasks.size(); i++) {
201 TaskSimulator task = finishTasks.elementAt(i);
202 this.tasks.removeElement(task);
203 if(task instanceof TransTaskSimulator) {
204 TransTaskSimulator tmptask = (TransTaskSimulator)task;
205 // add ADDOBJ task to targetCore
206 int targetCoreNum = tmptask.getTargetCoreNum();
207 ObjectSimulator nobj = tmptask.refreshTask();
208 this.cores.elementAt(targetCoreNum).addObject(nobj);
209 action = new Action(targetCoreNum, Action.ADDOBJ, 1, nobj.getCd());
210 cp.addAction(action);
211 if(!tmptask.isFinished()) {
212 // still have some objects to be transpotted
213 this.tasks.add(task);
215 if(this.cores.elementAt(targetCoreNum).getRtask() == null) {
216 TaskSimulator newTask = this.cores.elementAt(targetCoreNum).process();
217 if(newTask != null) {
218 this.tasks.add(newTask);
219 // add a TASKSTART action into this checkpoint
220 action = new Action(targetCoreNum, Action.TASKSTART);
221 action.setTd(newTask.getTd());
222 cp.addAction(action);
226 CoreSimulator cs = task.getCs();
227 int coreNum = cs.getCoreNum();
228 Hashtable<Integer, Queue<ObjectSimulator>> transObjQueues = new Hashtable<Integer, Queue<ObjectSimulator>>();
229 if(task.getCurrentRun().getNewObjs() == null) {
230 action = new Action(coreNum, Action.TASKFINISH);
231 action.setTd(cs.getRtask().getTd());
233 action = new Action(coreNum, Action.TFWITHOBJ);
234 action.setTd(cs.getRtask().getTd());
235 Vector<ObjectSimulator> nobjs = task.getCurrentRun().getNewObjs();
236 //Schedule schedule = this.scheduling.elementAt(coreNum);
237 for(int j = 0; j < nobjs.size(); j++) {
238 ObjectSimulator nobj = nobjs.elementAt(j);
239 action.addNewObj(nobj.getCd(), Integer.valueOf(1));
240 // send the new object to target core according to pre-decide scheduling
241 Queue<Integer> cores = cs.getTargetCores(nobj.getCurrentFS());
243 // this obj will reside on this core
246 Integer targetCore = cores.poll();
247 if(targetCore == coreNum) {
248 // this obj will reside on this core
251 if(!transObjQueues.containsKey(targetCore)) {
252 transObjQueues.put(targetCore, new LinkedList<ObjectSimulator>());
254 Queue<ObjectSimulator> tmpqueue = transObjQueues.get(targetCore);
257 // enqueue this core again
258 cores.add(targetCore);
262 cp.addAction(action);
263 Vector<ObjectSimulator> transObjs = cs.finishTask();
264 if(transObjs != null) {
265 for(int j = 0; j < transObjs.size(); j++) {
266 ObjectSimulator tobj = transObjs.elementAt(j);
267 // send the object to target core according to pre-decide scheduling
268 Queue<Integer> cores = cs.getTargetCores(tobj.getCurrentFS());
269 tobj.setCurrentFS(cs.getTargetFState(tobj.getCurrentFS()));
271 // this obj will reside on this core
274 Integer targetCore = cores.peek();
275 if(targetCore == coreNum) {
276 // this obj will reside on this core
279 if(!transObjQueues.containsKey(targetCore)) {
280 transObjQueues.put(targetCore, new LinkedList<ObjectSimulator>());
282 Queue<ObjectSimulator> tmpqueue = transObjQueues.get(targetCore);
288 // add 'transport' tasks
289 Iterator it_entries = transObjQueues.entrySet().iterator();
290 while(it_entries.hasNext()) {
291 Entry<Integer, Queue<ObjectSimulator>> tmpentry = (Entry<Integer, Queue<ObjectSimulator>>)it_entries.next();
292 Integer tmpCoreNum = tmpentry.getKey();
293 Queue<ObjectSimulator> nobjs = tmpentry.getValue();
294 TransTaskSimulator tmptask = new TransTaskSimulator(cs, tmpCoreNum, nobjs);
295 this.tasks.add(tmptask);
297 // Choose a new task for this core
298 TaskSimulator newTask = cs.process();
299 if(newTask != null) {
300 this.tasks.add(newTask);
301 // add a TASKSTART action into this checkpoint
302 action = new Action(coreNum, Action.TASKSTART);
303 action.setTd(cs.getRtask().getTd());
304 cp.addAction(action);
308 this.checkpoints.add(cp);
311 SchedulingUtil.printSimulationResult("SimulatorResult_" + this.invoketime + ".dot", this.processTime,
312 this.coreNum, this.checkpoints);
313 System.out.println("Simulate scheduling #" + this.invoketime + ": ");
314 System.out.println("\tTotal execution time is: " + this.processTime);
315 System.out.println("\tUtility of cores: ");
316 for(int j = 0; j < this.cores.size(); j++) {
317 System.out.println("\t\tcore" + j + ": " + getUtility(j) + "%");
319 return this.processTime;
322 public class CheckPoint {
323 private int timepoint;
324 private Vector<Action> actions;
326 public CheckPoint(int timepoint) {
328 this.timepoint = timepoint;
329 this.actions = new Vector<Action>();
332 public Vector<Action> getActions() {
336 public void addAction(Action action) {
337 this.actions.add(action);
340 public int getTimepoint() {
345 public class Action {
346 public static final int ADDOBJ = 0;
347 public static final int TASKFINISH = 1;
348 public static final int TFWITHOBJ = 2;
349 public static final int TASKSTART = 3;
353 private TaskDescriptor td;
354 private Hashtable<ClassDescriptor, Integer> nObjs;
356 private ClassDescriptor transObj;
358 public Action(int coreNum, int type) {
360 this.coreNum = coreNum;
363 if(this.type == TFWITHOBJ) {
364 this.nObjs = new Hashtable<ClassDescriptor, Integer>();
369 this.transObj = null;
372 public Action(int coreNum, int type, int objNum, ClassDescriptor transObj) {
374 assert(type == ADDOBJ);
375 this.coreNum = coreNum;
378 this.nObjNum = objNum;
379 this.transObj = transObj;
382 public void addNewObj(ClassDescriptor cd, Integer num) {
383 assert(this.type == TFWITHOBJ);
385 if(this.nObjs.containsKey(cd)) {
386 Integer sum = this.nObjs.get(cd) + num;
387 this.nObjs.put(cd, sum);
389 this.nObjs.put(cd, num);
393 public int getCoreNum() {
397 public int getType() {
401 public int getNObjNum() {
405 public ClassDescriptor getTransObj() {
409 public TaskDescriptor getTd() {
413 public void setTd(TaskDescriptor td) {
417 public Hashtable<ClassDescriptor, Integer> getNObjs() {