switch to spaces only..
[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     long ftime = 0;
291     for(int i = 0; i < paraQueues.size(); i++) {
292       ObjectSimulator tpara = paraQueues.elementAt(i).peek();
293
294       FlagState tfstate = tpara.getCurrentFS();
295       FEdge toexecute = tfstate.process(td);
296       finishTime += toexecute.getExeTime();
297       // TODO for test
298       if(ftime == 0) {
299         ftime = toexecute.getExeTime();
300       } else if(ftime != toexecute.getExeTime()) {
301         //System.err.println("error for simulation: " + td.getSymbol());
302       }
303       // TODO for test
304       /*if(td.getSymbol().equals("addIYLM")) {
305          System.err.println("# " + i + " time: " + toexecute.getExeTime());
306          }*/
307       if((toexecute.getNewObjInfoHashtable() != null)
308          && (toexecute.getNewObjInfoHashtable().size() > 0)) {
309         // have new objects
310         Iterator it = toexecute.getNewObjInfoHashtable().keySet().iterator();
311         int invokeNum = toexecute.getInvokeNum();
312         while(it.hasNext()) {
313           ClassDescriptor cd = (ClassDescriptor)it.next();
314           NewObjInfo noi = toexecute.getNewObjInfo(cd);
315           if(noi.getInvokeNum() < ((int)Math.round(((noi.getProbability() / 100) * noi.getNewRate() * invokeNum)))) {
316             for(int j = 0; j < noi.getNewRate(); j++) {
317               ObjectSimulator tmpObj = new ObjectSimulator(cd, noi.getRoot());
318               this.currentRun.addNewObj(tmpObj);
319               noi.incInvokeNum();
320             }
321           }
322         }
323       }
324       tpara.applyEdge(toexecute);
325       tpara.increaseVersion();
326     }
327     finishTime /= paraQueues.size();
328 //  TODO for test
329     /*if(td.getSymbol().equals("addIYLM")) {
330        System.err.println("total time: " + finishTime);
331        System.err.println("=====");
332        }*/
333     this.currentRun.setFinishTime(finishTime);
334     this.currentRun.setExetype(0);
335   }
336
337   public void updateFinishTime(long time) {
338     this.currentRun.setFinishTime(this.currentRun.finishTime - time);
339     finish = false;
340   }
341
342   public void finish() {
343     this.finish = true;
344   }
345 }