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