Add new feature of splitting nodes into Scheduling algorithm and fix some bugs in...
[IRC.git] / Robust / src / Analysis / Scheduling / ScheduleNode.java
1 package Analysis.Scheduling;
2
3 import Analysis.TaskStateAnalysis.*;
4 import IR.*;
5 import java.util.*;
6
7 import Util.GraphNode;
8
9 /** This class holds flag transition diagram(s) can be put on one core.
10  */
11 public class ScheduleNode extends GraphNode implements Cloneable{
12     
13     private int uid;
14     private static int nodeID=0;
15
16     private Vector<ClassNode> classNodes;
17     Vector<ScheduleEdge> scheduleEdges;
18     
19     private int executionTime;
20     
21     private int coreNum;
22     private Vector tasks;
23     private Hashtable<ClassDescriptor, Vector<ScheduleNode>> targetSNodes; 
24     private boolean sorted = false;
25
26     /** Class constructor
27      *  @param cd ClassDescriptor
28      *  @param fStates
29      */
30     public ScheduleNode() {
31         this.uid=ScheduleNode.nodeID++;
32         this.coreNum = -1;
33         this.executionTime = -1;
34     }
35     
36     public ScheduleNode(ClassNode cn) {
37         this.uid=ScheduleNode.nodeID++;
38         this.coreNum = -1;
39         this.classNodes = new Vector<ClassNode>();
40         this.scheduleEdges = new Vector<ScheduleEdge>();
41         this.classNodes.add(cn);
42         this.addEdge(cn.getEdgeVector());
43         this.executionTime = -1;
44     }
45    
46     public int getuid() {
47         return uid;
48     }
49     
50     public int getCoreNum() {
51         return this.coreNum;
52     }
53     
54     public void setCoreNum(int coreNum) {
55         this.coreNum = coreNum;
56     }
57     
58     public void addTargetSNode(ClassDescriptor cd, ScheduleNode sn) {
59         if(this.targetSNodes == null) {
60             this.targetSNodes = new Hashtable<ClassDescriptor, Vector<ScheduleNode>>();
61         }
62         
63         if(!this.targetSNodes.containsKey(cd)) {
64             this.targetSNodes.put(cd, new Vector<ScheduleNode>());
65         }
66         this.targetSNodes.get(cd).add(sn);
67     }
68     
69     public void listTasks() {
70         if(this.tasks == null) {
71             this.tasks = new Vector();
72         }
73         
74         int i = 0;
75         for(i = 0; i < classNodes.size(); i++) {
76             Iterator it_flags = classNodes.elementAt(i).getFlags();
77             while(it_flags.hasNext()) {
78                 FlagState fs = (FlagState)it_flags.next();
79                 Iterator it_edges = fs.edges();
80                 while(it_edges.hasNext()) {
81                     TaskDescriptor td = ((FEdge)it_edges.next()).getTask();
82                     if(!this.tasks.contains(td)) {
83                         this.tasks.add(td);
84                     }
85                 }
86             }
87         }
88     }
89     
90     public void addTask(TaskDescriptor task){
91         tasks.add(task);
92     }
93     
94     public Vector getTasks(){
95         return tasks;
96     }
97     
98     public boolean isSorted() {
99         return sorted;
100     }
101     
102     public void setSorted(boolean sorted) {
103         this.sorted = sorted;
104     }
105     
106     public String toString() {
107         String temp = new String("");
108         for(int i = 0; i < classNodes.size(); i++) {
109             temp += classNodes.elementAt(i).getClassDescriptor().toString() + ", ";
110         }
111         temp += getTextLabel();
112         return temp;
113     }
114     
115     public Vector getClassNodes() {
116         if(classNodes == null) {
117             classNodes = new Vector<ClassNode>();
118         }
119         return classNodes;
120     }
121     
122     public Iterator getClassNodesIterator() {
123         return classNodes.iterator();
124     }
125     
126     public void resetClassNodes() {
127         classNodes = null;
128     }
129     
130     public Vector getScheduleEdges() {
131         if(scheduleEdges == null) {
132             scheduleEdges = new Vector<ScheduleEdge>();
133         }
134         return scheduleEdges;
135     }
136     
137     public Iterator getScheduleEdgesIterator() {
138         return scheduleEdges.iterator();
139     }
140     
141     public void resetScheduleEdges() {
142         scheduleEdges = null;
143     }
144     
145     public int getExeTime() {
146         if(this.executionTime == -1) {
147             try {
148                 calExeTime();
149             } catch (Exception e) {
150                 e.printStackTrace();
151             }
152         }
153         return this.executionTime;
154     }
155     
156     public void calExeTime() throws Exception {
157         if(this.classNodes.size() != 1) {
158             throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
159         }
160         ClassNode cn = this.classNodes.elementAt(0);
161         if(!cn.isSorted()) {
162             throw new Error("Error: Non-sorted ClassNode!");
163         }
164         this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
165     }
166     
167     /** Tests for equality of two flagstate objects.
168     */
169     
170     public boolean equals(Object o) {
171         if (o instanceof ScheduleNode) {
172             ScheduleNode fs=(ScheduleNode)o;
173             if ((fs.getCoreNum() != this.coreNum) ||
174                 (fs.sorted != this.sorted) ||
175                 (fs.executionTime != this.executionTime)){ 
176                 return false;
177             }
178             if(fs.tasks != null) {
179                 if(!fs.tasks.equals(this.tasks)) {
180                     return false;
181                 }
182             } else if (tasks != null) {
183                 return false;
184             }
185             if (fs.targetSNodes != null) {
186                 if(!fs.targetSNodes.equals(this.targetSNodes)) {
187                     return false;
188                 }
189             } else if(this.targetSNodes != null) {
190                 return false;
191             }
192             if(fs.classNodes != null) {
193                 if(!fs.classNodes.equals(classNodes)) {
194                     return false;
195                 }
196             } else if(classNodes != null) {
197                 return false;
198             }
199             return (fs.scheduleEdges.equals(scheduleEdges));
200         }
201         return false;
202     }
203
204     public int hashCode() {
205         return classNodes.hashCode()^scheduleEdges.hashCode();
206     }
207
208     public String getLabel() {
209         return "cluster" + uid;
210     }   
211
212     public String getTextLabel() {
213         String label=null;
214         if(this.coreNum != -1) {
215             label = "Core " + this.coreNum;
216         }
217         
218         if (label==null)
219             return " ";
220         return label;
221     }
222     
223     public Object clone(Hashtable<ClassNode, ClassNode> cn2cn) {
224         ScheduleNode o = null;
225         try {
226             o = (ScheduleNode)super.clone();
227         } catch(CloneNotSupportedException e){
228             e.printStackTrace();
229         }
230         o.uid = ScheduleNode.nodeID++;
231         // Clone all the internal ClassNodes and ScheduleEdges
232         Vector<ClassNode> tcns = new Vector<ClassNode>();
233         Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
234         int i = 0;
235         for(i = 0; i < this.classNodes.size(); i++) {
236             ClassNode tcn = this.classNodes.elementAt(i);
237             ClassNode cn = (ClassNode)tcn.clone();
238             cn.setScheduleNode(o);
239             tcns.add(cn);
240             cn2cn.put(tcn, cn);
241         }
242         for(i = 0; i < this.scheduleEdges.size(); i++) {
243             ScheduleEdge temp = this.scheduleEdges.elementAt(i);
244             ScheduleEdge se = null;
245             if(!temp.getIsNew()) {
246                 se = new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false);
247             } else {
248                 se = new ScheduleEdge(o, "new",temp.getClassDescriptor());
249             }
250             se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
251             se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
252             se.setProbability(temp.getProbability());
253             se.setNewRate(temp.getNewRate());
254             se.setTransTime(temp.getTransTime());
255             tses.add(se);
256         }
257         o.classNodes = tcns;
258         o.scheduleEdges = tses;
259         tcns = null;
260         tses = null;
261         o.inedges = new Vector();
262         o.edges = new Vector();
263
264         return o;
265     }
266     
267     public void mergeSEdge(ScheduleEdge se) {
268         assert(se.getIsNew());
269         
270         Vector<ClassNode> targetCNodes = (Vector<ClassNode>)((ScheduleNode)se.getTarget()).getClassNodes();
271         Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)((ScheduleNode)se.getTarget()).getScheduleEdges();
272         
273         for(int i = 0; i <  targetCNodes.size(); i++) {
274             targetCNodes.elementAt(i).setScheduleNode(this);
275         }
276         
277         if(classNodes == null) {
278             classNodes = targetCNodes;
279             scheduleEdges = targetSEdges;
280         } else {
281             if(targetCNodes.size() != 0) {
282                 classNodes.addAll(targetCNodes);
283             }
284             if(targetSEdges.size() != 0) {
285                 scheduleEdges.addAll(targetSEdges);
286             }
287         }
288         targetCNodes = null;
289         targetSEdges = null;
290         
291         scheduleEdges.add(se);
292         se.resetListExeTime();
293         se.getTarget().removeInedge(se);
294         this.removeEdge(se);
295         Iterator it_edges = se.getTarget().edges();
296         while(it_edges.hasNext()) {
297             ScheduleEdge tse = (ScheduleEdge)it_edges.next();
298             tse.setSource(this);
299             this.edges.addElement(tse);
300         }
301         
302         // As all tasks inside one ScheduleNode are executed sequentially,
303         // simply add the execution time of all the ClassNodes inside one ScheduleNode. 
304         if(this.executionTime == -1) {
305             this.executionTime = 0;
306         }
307         this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
308     }
309     
310     public void mergeSNode(ScheduleNode sn) throws Exception {
311         Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
312         Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
313         
314         for(int i = 0; i <  targetCNodes.size(); i++) {
315             targetCNodes.elementAt(i).setScheduleNode(this);
316         }
317         
318         if(classNodes == null) {
319             classNodes = targetCNodes;
320             scheduleEdges = targetSEdges;
321         } else {
322             if(targetCNodes.size() != 0) {
323                 classNodes.addAll(targetCNodes);
324             }
325             if(targetSEdges.size() != 0) {
326                 scheduleEdges.addAll(targetSEdges);
327             }
328         }
329         targetCNodes = null;
330         targetSEdges = null;
331
332         Iterator it_edges = sn.edges();
333         while(it_edges.hasNext()) {
334             ScheduleEdge tse = (ScheduleEdge)it_edges.next();
335             tse.setSource(this);
336             this.edges.addElement(tse);
337         }
338         
339         // As all tasks inside one ScheduleNode are executed sequentially,
340         // simply add the execution time of all the ClassNodes inside one ScheduleNode. 
341         if(this.executionTime == -1) {
342             throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
343         }
344         if(this.executionTime < sn.getExeTime()) {
345             this.executionTime = sn.getExeTime();
346         }
347     }
348 }