bug fix in scheduling and multicore support for tags
[IRC.git] / Robust / src / Analysis / Scheduling / TaskSimulator.java
1 package Analysis.Scheduling;
2
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
9 import Analysis.TaskStateAnalysis.FEdge;
10 import Analysis.TaskStateAnalysis.FlagState;
11 import Analysis.TaskStateAnalysis.FEdge.NewObjInfo;
12 import IR.ClassDescriptor;
13 import IR.TaskDescriptor;
14 import IR.VarDescriptor;
15 import IR.Tree.FlagExpressionNode;
16
17 public class TaskSimulator {
18   TaskDescriptor td;
19   Vector<Queue<ObjectSimulator>> paraQueues;
20   Hashtable<ObjectSimulator, Integer> objVersionTbl;
21   ExeResult currentRun;
22   CoreSimulator cs;
23   boolean finish;
24
25   public class ExeResult {
26     long finishTime;
27     Vector<ObjectSimulator> newObjs;
28     int exetype;     // 0--normal executing
29                      // 1--abort due to fail on grabbing locks
30                      // 2--out of date task
31
32     public ExeResult() {
33       finishTime = 0;
34       newObjs = null;
35     }
36
37     public long getFinishTime() {
38       return finishTime;
39     }
40
41     public void setFinishTime(long finishTime) {
42       this.finishTime = finishTime;
43     }
44
45     public Vector<ObjectSimulator> getNewObjs() {
46       return newObjs;
47     }
48
49     public void addNewObj(ObjectSimulator newObj) {
50       if(this.newObjs == null) {
51         this.newObjs = new Vector<ObjectSimulator>();
52       }
53
54       this.newObjs.add(newObj);
55     }
56
57     public int getExetype() {
58       return exetype;
59     }
60
61     public void setExetype(int exetype) {
62       this.exetype = exetype;
63     }
64
65     public void init() {
66       finishTime = 0;
67       if(newObjs != null) {
68         newObjs.clear();
69       }
70     }
71   }
72
73   public TaskSimulator(TaskDescriptor td, 
74                        CoreSimulator cs) {
75     super();
76     this.td = td;
77     this.paraQueues = null;
78     this.objVersionTbl = null;
79     this.currentRun = null;
80     this.cs = cs;
81     this.finish = true;
82   }
83
84   public CoreSimulator getCs() {
85     return cs;
86   }
87
88   public TaskDescriptor getTd() {
89     return td;
90   }
91
92   public ExeResult getCurrentRun() {
93     return currentRun;
94   }
95
96   public Vector<Queue<ObjectSimulator>> getParaQueues() {
97     return paraQueues;
98   }
99
100   public Hashtable<ObjectSimulator, Integer> getObjVersionTbl() {
101     return objVersionTbl;
102   }
103
104   public int getObjVersion(ObjectSimulator os) {
105     return this.objVersionTbl.get(os).intValue();
106   }
107
108   public void enquePara(ObjectSimulator obj, 
109                         FlagState fs, 
110                         int version, 
111                         boolean inherent) {
112     ClassDescriptor cd = obj.getCd();
113     int paraNum = td.numParameters();
114     for(int i = 0; i < paraNum; i++) {
115       VarDescriptor para = td.getParameter(i);
116       if(cd.equals(para.getType().getClassDesc())) {
117         // check if the status is right
118         FlagExpressionNode fen = td.getFlag(para);
119         FlagState cfs = fs;
120         if(inherent) {
121           cfs = obj.getCurrentFS();
122         }
123         if(SchedulingUtil.isTaskTrigger_flag(fen, cfs)) {
124           if(this.paraQueues == null) {
125             this.paraQueues = new Vector<Queue<ObjectSimulator>>();
126             for(int j = 0; j < paraNum; j++) {
127               this.paraQueues.add(null);
128             }
129           }
130           if(this.paraQueues.elementAt(i) == null) {
131             this.paraQueues.setElementAt(new LinkedList<ObjectSimulator>(), i);
132           }
133           if(this.objVersionTbl == null) {
134             this.objVersionTbl = new Hashtable<ObjectSimulator, Integer>();
135           }
136           if(!this.paraQueues.elementAt(i).contains(obj)) {
137             this.paraQueues.elementAt(i).add(obj);
138             if(inherent) {
139               this.objVersionTbl.put(obj, obj.getVersion());
140             } else {
141               this.objVersionTbl.put(obj, version);
142             }
143           }
144         }
145       }
146     }
147   }
148
149   public void refreshPara(ObjectSimulator obj, 
150                           boolean remove) {
151     ClassDescriptor cd = obj.getCd();
152     int paraNum = td.numParameters();
153     for(int i = 0; i < paraNum; i++) {
154       VarDescriptor para = td.getParameter(i);
155       if(cd.equals(para.getType().getClassDesc())) {
156         if(remove) {
157           if((this.paraQueues != null) &&
158              (this.paraQueues.elementAt(i) != null)  &&
159              (this.paraQueues.elementAt(i).contains(obj))) {
160             this.paraQueues.elementAt(i).remove(obj);
161             this.objVersionTbl.remove(obj);
162           }
163         } else {
164           // check if the status is right
165           FlagExpressionNode fen = td.getFlag(para);
166           if(SchedulingUtil.isTaskTrigger_flag(fen, obj.getCurrentFS())) {
167             if(this.paraQueues == null) {
168               this.paraQueues = new Vector<Queue<ObjectSimulator>>();
169               for(int j = 0; j < paraNum; j++) {
170                 this.paraQueues.add(null);
171               }
172             }
173             if(this.paraQueues.elementAt(i) == null) {
174               this.paraQueues.setElementAt(new LinkedList<ObjectSimulator>(), i);
175             }
176             this.paraQueues.elementAt(i).add(obj);
177             if(this.objVersionTbl == null) {
178               this.objVersionTbl = new Hashtable<ObjectSimulator, Integer>();
179             }
180             this.objVersionTbl.put(obj, obj.getVersion());
181           } else {
182             if((this.paraQueues != null) &&
183                (this.paraQueues.elementAt(i) != null)  &&
184                (this.paraQueues.elementAt(i).contains(obj))) {
185               this.paraQueues.elementAt(i).remove(obj);
186               this.objVersionTbl.remove(obj);
187             }
188           }
189         }
190       }
191     }
192   }
193
194   public void process() {
195     if(!finish) {
196       return;
197     } else {
198       finish = false;
199     }
200
201     if(this.currentRun == null) {
202       this.currentRun = new ExeResult();
203     } else {
204       this.currentRun.init();
205     }
206
207     long finishTime = 0;
208     // According to runtime statistic information, decide the execution path of this task this time.
209     // Mainly following things:
210     //    1.the result, i.e. the result FlagState reached by each parameter.
211     //    2.the finish time
212     //    3.any new objects
213
214     // First check if all the parameters are still available.
215     // For shared objects, need to first grab the lock and also check if the version is right
216     for(int i = 0; i < paraQueues.size(); i++) {
217       ObjectSimulator tpara = paraQueues.elementAt(i).peek();
218       if(tpara == null) {
219         // the parameter is already removed, delete this task too
220         finishTime = 800;
221         this.currentRun.setFinishTime(finishTime);
222         this.currentRun.setExetype(2);
223         for(int j = 0; j < i; ++j) {
224           tpara = this.paraQueues.elementAt(j).poll();
225           if(tpara.isShared() && tpara.isHold()) {
226             tpara.setHold(false);
227           }
228           this.paraQueues.elementAt(j).add(tpara);
229         }
230         return;
231       }
232       if(tpara.isShared()) {
233         if(tpara.isHold()) {
234           // shared object held by other tasks
235           finishTime = 800;           // TODO currenly assume the effort on requesting locks are only 800
236           /*this.currentRun.setFinishTime(finishTime);
237           this.currentRun.setExetype(1);
238           paraQueues.elementAt(i).poll();
239           paraQueues.elementAt(i).add(tpara);
240           for(int j = 0; j < i; ++j) {
241             tpara = this.paraQueues.elementAt(j).poll();
242             if(tpara.isShared() && tpara.isHold()) {
243               tpara.setHold(false);
244             }
245             this.paraQueues.elementAt(j).add(tpara);
246           }*/
247           // remove it instead
248           this.currentRun.setFinishTime(finishTime);
249           this.currentRun.setExetype(2);
250           paraQueues.elementAt(i).poll();
251           // remove this object from the remaining parameter queues
252           for(int j = i + 1; j < paraQueues.size(); j++) {
253             paraQueues.elementAt(j).remove(tpara);
254           }
255           for(int j = 0; j < i; ++j) {
256             tpara = this.paraQueues.elementAt(j).poll();
257             if(tpara.isShared() && tpara.isHold()) {
258               tpara.setHold(false);
259             }
260             this.paraQueues.elementAt(j).add(tpara);
261           }
262           return;
263         } else if (tpara.getVersion() != this.objVersionTbl.get(tpara)) {
264           // shared object has been updated and no longer fitted to this task
265           finishTime = 800;           // TODO currenly assume the effort on requesting locks are only 800
266           this.currentRun.setFinishTime(finishTime);
267           this.currentRun.setExetype(2);
268           paraQueues.elementAt(i).poll();
269           // remove this object from the remaining parameter queues
270           for(int j = i + 1; j < paraQueues.size(); j++) {
271             paraQueues.elementAt(j).remove(tpara);
272           }
273           for(int j = 0; j < i; ++j) {
274             tpara = this.paraQueues.elementAt(j).poll();
275             if(tpara.isShared() && tpara.isHold()) {
276               tpara.setHold(false);
277             }
278             this.paraQueues.elementAt(j).add(tpara);
279           }
280           return;
281         } else {
282           tpara.setHold(true);
283         }
284       }
285       // remove this object from the remaining parameter queues
286       for(int j = i + 1; j < paraQueues.size(); j++) {
287         paraQueues.elementAt(j).remove(tpara);
288       }
289     }
290     for(int i = 0; i < paraQueues.size(); i++) {
291       ObjectSimulator tpara = paraQueues.elementAt(i).peek();
292
293       FlagState tfstate = tpara.getCurrentFS();
294       FEdge toexecute = tfstate.process(td);
295       finishTime += toexecute.getExeTime();
296       if((toexecute.getNewObjInfoHashtable() != null) 
297               && (toexecute.getNewObjInfoHashtable().size() > 0)) {
298         // have new objects
299         Iterator it = toexecute.getNewObjInfoHashtable().keySet().iterator();
300         int invokeNum = toexecute.getInvokeNum();
301         while(it.hasNext()) {
302           ClassDescriptor cd = (ClassDescriptor)it.next();
303           NewObjInfo noi = toexecute.getNewObjInfo(cd);
304           if(noi.getInvokeNum() < ((int)Math.round(((noi.getProbability() / 100) * noi.getNewRate() * invokeNum)))) {
305             for(int j = 0; j < noi.getNewRate(); j++) {
306               ObjectSimulator tmpObj = new ObjectSimulator(cd, noi.getRoot());
307               this.currentRun.addNewObj(tmpObj);
308               noi.incInvokeNum();
309             }
310           }
311         }
312       }
313       tpara.applyEdge(toexecute);
314       tpara.increaseVersion();
315     }
316     finishTime /= paraQueues.size();
317     this.currentRun.setFinishTime(finishTime);
318     this.currentRun.setExetype(0);
319   }
320
321   public void updateFinishTime(long time) {
322     this.currentRun.setFinishTime(this.currentRun.finishTime - time);
323     finish = false;
324   }
325
326   public void finish() {
327     this.finish = true;
328   }
329 }