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