Fix bugs in scheduling simulator. Also add -robustroot setting in Tests/dotest script
[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     int 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 int getFinishTime() {
38       return finishTime;
39     }
40
41     public void setFinishTime(int 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, CoreSimulator cs) {
74     super();
75     this.td = td;
76     this.paraQueues = null;
77     this.objVersionTbl = null;
78     this.currentRun = null;
79     this.cs = cs;
80     this.finish = true;
81   }
82
83   public CoreSimulator getCs() {
84     return cs;
85   }
86
87   public TaskDescriptor getTd() {
88     return td;
89   }
90
91   public ExeResult getCurrentRun() {
92     return currentRun;
93   }
94
95   public Vector<Queue<ObjectSimulator>> getParaQueues() {
96     return paraQueues;
97   }
98
99   public Hashtable<ObjectSimulator, Integer> getObjVersionTbl() {
100     return objVersionTbl;
101   }
102
103   public int getObjVersion(ObjectSimulator os) {
104     return this.objVersionTbl.get(os).intValue();
105   }
106
107   public void enquePara(ObjectSimulator obj, FlagState fs, int version, boolean inherent) {
108     ClassDescriptor cd = obj.getCd();
109     int paraNum = td.numParameters();
110     for(int i = 0; i < paraNum; i++) {
111       VarDescriptor para = td.getParameter(i);
112       if(cd.equals(para.getType().getClassDesc())) {
113         // check if the status is right
114         FlagExpressionNode fen = td.getFlag(para);
115         FlagState cfs = fs;
116         if(inherent) {
117           cfs = obj.getCurrentFS();
118         }
119         if(SchedulingUtil.isTaskTrigger_flag(fen, cfs)) {
120           if(this.paraQueues == null) {
121             this.paraQueues = new Vector<Queue<ObjectSimulator>>();
122             for(int j = 0; j < paraNum; j++) {
123               this.paraQueues.add(null);
124             }
125           }
126           if(this.paraQueues.elementAt(i) == null) {
127             this.paraQueues.setElementAt(new LinkedList<ObjectSimulator>(), i);
128           }
129           if(this.objVersionTbl == null) {
130             this.objVersionTbl = new Hashtable<ObjectSimulator, Integer>();
131           }
132           if(!this.paraQueues.elementAt(i).contains(obj)) {
133             this.paraQueues.elementAt(i).add(obj);
134             if(inherent) {
135               this.objVersionTbl.put(obj, obj.getVersion());
136             } else {
137               this.objVersionTbl.put(obj, version);
138             }
139           }
140         }
141       }
142     }
143   }
144
145   public void refreshPara(ObjectSimulator obj, boolean remove) {
146     ClassDescriptor cd = obj.getCd();
147     int paraNum = td.numParameters();
148     for(int i = 0; i < paraNum; i++) {
149       VarDescriptor para = td.getParameter(i);
150       if(cd.equals(para.getType().getClassDesc())) {
151         if(remove) {
152           if((this.paraQueues != null) &&
153              (this.paraQueues.elementAt(i) != null)  &&
154              (this.paraQueues.elementAt(i).contains(obj))) {
155             this.paraQueues.elementAt(i).remove(obj);
156             this.objVersionTbl.remove(obj);
157           }
158         } else {
159           // check if the status is right
160           FlagExpressionNode fen = td.getFlag(para);
161           if(SchedulingUtil.isTaskTrigger_flag(fen, obj.getCurrentFS())) {
162             if(this.paraQueues == null) {
163               this.paraQueues = new Vector<Queue<ObjectSimulator>>();
164               for(int j = 0; j < paraNum; j++) {
165                 this.paraQueues.add(null);
166               }
167             }
168             if(this.paraQueues.elementAt(i) == null) {
169               this.paraQueues.setElementAt(new LinkedList<ObjectSimulator>(), i);
170             }
171             this.paraQueues.elementAt(i).add(obj);
172             if(this.objVersionTbl == null) {
173               this.objVersionTbl = new Hashtable<ObjectSimulator, Integer>();
174             }
175             this.objVersionTbl.put(obj, obj.getVersion());
176           } else {
177             if((this.paraQueues != null) &&
178                (this.paraQueues.elementAt(i) != null)  &&
179                (this.paraQueues.elementAt(i).contains(obj))) {
180               this.paraQueues.elementAt(i).remove(obj);
181               this.objVersionTbl.remove(obj);
182             }
183           }
184         }
185       }
186     }
187   }
188
189   public void process() {
190     if(!finish) {
191       return;
192     } else {
193       finish = false;
194     }
195
196     if(this.currentRun == null) {
197       this.currentRun = new ExeResult();
198     } else {
199       this.currentRun.init();
200     }
201
202     int finishTime = 0;
203     // According to runtime statistic information, decide the execution path of this task this time.
204     // Mainly following things:
205     //    1.the result, i.e. the result FlagState reached by each parameter.
206     //    2.the finish time
207     //    3.any new objects
208
209     // First check if all the parameters are still available.
210     // For shared objects, need to first grab the lock and also check if the version is right
211     for(int i = 0; i < paraQueues.size(); i++) {
212       ObjectSimulator tpara = paraQueues.elementAt(i).peek();
213       if(tpara.isShared()) {
214         if(tpara.isHold()) {
215           // shared object held by other tasks
216           finishTime = 800;           // TODO currenly assume the effort on requesting locks are only 800
217           /*this.currentRun.setFinishTime(finishTime);
218           this.currentRun.setExetype(1);
219           paraQueues.elementAt(i).poll();
220           paraQueues.elementAt(i).add(tpara);
221           for(int j = 0; j < i; ++j) {
222             tpara = this.paraQueues.elementAt(j).poll();
223             if(tpara.isShared() && tpara.isHold()) {
224               tpara.setHold(false);
225             }
226             this.paraQueues.elementAt(j).add(tpara);
227           }*/
228           // remove it instead
229           this.currentRun.setFinishTime(finishTime);
230           this.currentRun.setExetype(2);
231           paraQueues.elementAt(i).poll();
232           // remove this object from the remaining parameter queues
233           for(int j = i + 1; j < paraQueues.size(); j++) {
234             paraQueues.elementAt(j).remove(tpara);
235           }
236           for(int j = 0; j < i; ++j) {
237             tpara = this.paraQueues.elementAt(j).poll();
238             if(tpara.isShared() && tpara.isHold()) {
239               tpara.setHold(false);
240             }
241             this.paraQueues.elementAt(j).add(tpara);
242           }
243           return;
244         } else if (tpara.getVersion() != this.objVersionTbl.get(tpara)) {
245           // shared object has been updated and no longer fitted to this task
246           finishTime = 800;           // TODO currenly assume the effort on requesting locks are only 800
247           this.currentRun.setFinishTime(finishTime);
248           this.currentRun.setExetype(2);
249           paraQueues.elementAt(i).poll();
250           // remove this object from the remaining parameter queues
251           for(int j = i + 1; j < paraQueues.size(); j++) {
252             paraQueues.elementAt(j).remove(tpara);
253           }
254           for(int j = 0; j < i; ++j) {
255             tpara = this.paraQueues.elementAt(j).poll();
256             if(tpara.isShared() && tpara.isHold()) {
257               tpara.setHold(false);
258             }
259             this.paraQueues.elementAt(j).add(tpara);
260           }
261           return;
262         } else {
263           tpara.setHold(true);
264         }
265       }
266       // remove this object from the remaining parameter queues
267       for(int j = i + 1; j < paraQueues.size(); j++) {
268         paraQueues.elementAt(j).remove(tpara);
269       }
270     }
271     for(int i = 0; i < paraQueues.size(); i++) {
272       ObjectSimulator tpara = paraQueues.elementAt(i).peek();
273
274       FlagState tfstate = tpara.getCurrentFS();
275       FEdge toexecute = tfstate.process(td);
276       finishTime += toexecute.getExeTime();
277       if((toexecute.getNewObjInfoHashtable() != null) && (toexecute.getNewObjInfoHashtable().size() > 0)) {
278         // have new objects
279         Iterator it = toexecute.getNewObjInfoHashtable().keySet().iterator();
280         int invokeNum = toexecute.getInvokeNum();
281         while(it.hasNext()) {
282           ClassDescriptor cd = (ClassDescriptor)it.next();
283           NewObjInfo noi = toexecute.getNewObjInfo(cd);
284           if(noi.getInvokeNum() < ((int)Math.round(((noi.getProbability() / 100) * noi.getNewRate() * invokeNum)))) {
285             for(int j = 0; j < noi.getNewRate(); j++) {
286               ObjectSimulator tmpObj = new ObjectSimulator(cd, noi.getRoot());
287               this.currentRun.addNewObj(tmpObj);
288               noi.incInvokeNum();
289             }
290           }
291         }
292       }
293       tpara.applyEdge(toexecute);
294       tpara.increaseVersion();
295     }
296     finishTime /= paraQueues.size();
297     this.currentRun.setFinishTime(finishTime);
298     this.currentRun.setExetype(0);
299   }
300
301   public void updateFinishTime(int time) {
302     this.currentRun.setFinishTime(this.currentRun.finishTime - time);
303     finish = false;
304   }
305
306   public void finish() {
307     this.finish = true;
308   }
309 }