start of new file
[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 }