changes to handle fixed point analysis properly + bug fix.
[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.isShared()) {
219         if(tpara.isHold()) {
220           // shared object held by other tasks
221           finishTime = 800;           // TODO currenly assume the effort on requesting locks are only 800
222           /*this.currentRun.setFinishTime(finishTime);
223           this.currentRun.setExetype(1);
224           paraQueues.elementAt(i).poll();
225           paraQueues.elementAt(i).add(tpara);
226           for(int j = 0; j < i; ++j) {
227             tpara = this.paraQueues.elementAt(j).poll();
228             if(tpara.isShared() && tpara.isHold()) {
229               tpara.setHold(false);
230             }
231             this.paraQueues.elementAt(j).add(tpara);
232           }*/
233           // remove it instead
234           this.currentRun.setFinishTime(finishTime);
235           this.currentRun.setExetype(2);
236           paraQueues.elementAt(i).poll();
237           // remove this object from the remaining parameter queues
238           for(int j = i + 1; j < paraQueues.size(); j++) {
239             paraQueues.elementAt(j).remove(tpara);
240           }
241           for(int j = 0; j < i; ++j) {
242             tpara = this.paraQueues.elementAt(j).poll();
243             if(tpara.isShared() && tpara.isHold()) {
244               tpara.setHold(false);
245             }
246             this.paraQueues.elementAt(j).add(tpara);
247           }
248           return;
249         } else if (tpara.getVersion() != this.objVersionTbl.get(tpara)) {
250           // shared object has been updated and no longer fitted to this task
251           finishTime = 800;           // TODO currenly assume the effort on requesting locks are only 800
252           this.currentRun.setFinishTime(finishTime);
253           this.currentRun.setExetype(2);
254           paraQueues.elementAt(i).poll();
255           // remove this object from the remaining parameter queues
256           for(int j = i + 1; j < paraQueues.size(); j++) {
257             paraQueues.elementAt(j).remove(tpara);
258           }
259           for(int j = 0; j < i; ++j) {
260             tpara = this.paraQueues.elementAt(j).poll();
261             if(tpara.isShared() && tpara.isHold()) {
262               tpara.setHold(false);
263             }
264             this.paraQueues.elementAt(j).add(tpara);
265           }
266           return;
267         } else {
268           tpara.setHold(true);
269         }
270       }
271       // remove this object from the remaining parameter queues
272       for(int j = i + 1; j < paraQueues.size(); j++) {
273         paraQueues.elementAt(j).remove(tpara);
274       }
275     }
276     for(int i = 0; i < paraQueues.size(); i++) {
277       ObjectSimulator tpara = paraQueues.elementAt(i).peek();
278
279       FlagState tfstate = tpara.getCurrentFS();
280       FEdge toexecute = tfstate.process(td);
281       finishTime += toexecute.getExeTime();
282       if((toexecute.getNewObjInfoHashtable() != null) 
283               && (toexecute.getNewObjInfoHashtable().size() > 0)) {
284         // have new objects
285         Iterator it = toexecute.getNewObjInfoHashtable().keySet().iterator();
286         int invokeNum = toexecute.getInvokeNum();
287         while(it.hasNext()) {
288           ClassDescriptor cd = (ClassDescriptor)it.next();
289           NewObjInfo noi = toexecute.getNewObjInfo(cd);
290           if(noi.getInvokeNum() < ((int)Math.round(((noi.getProbability() / 100) * noi.getNewRate() * invokeNum)))) {
291             for(int j = 0; j < noi.getNewRate(); j++) {
292               ObjectSimulator tmpObj = new ObjectSimulator(cd, noi.getRoot());
293               this.currentRun.addNewObj(tmpObj);
294               noi.incInvokeNum();
295             }
296           }
297         }
298       }
299       tpara.applyEdge(toexecute);
300       tpara.increaseVersion();
301     }
302     finishTime /= paraQueues.size();
303     this.currentRun.setFinishTime(finishTime);
304     this.currentRun.setExetype(0);
305   }
306
307   public void updateFinishTime(long time) {
308     this.currentRun.setFinishTime(this.currentRun.finishTime - time);
309     finish = false;
310   }
311
312   public void finish() {
313     this.finish = true;
314   }
315 }