1 package Analysis.Scheduling;
5 import Analysis.TaskStateAnalysis.FEdge;
6 import Analysis.TaskStateAnalysis.FlagState;
9 /** This class holds flag transition diagram(s) can be put on one core.
11 public class ScheduleNode extends GraphNode implements Cloneable {
16 private static int nodeID=0;
17 public static int colorID = 0;
19 private Vector<ClassNode> classNodes;
20 Vector<ScheduleEdge> scheduleEdges;
22 private int executionTime;
25 * @param cd ClassDescriptor
28 public ScheduleNode(int gid) {
29 this.uid = ScheduleNode.nodeID++;
32 this.executionTime = -1;
33 this.classNodes = null;
34 this.scheduleEdges = null;
37 public ScheduleNode(ClassNode cn, int gid) {
38 this.uid = ScheduleNode.nodeID++;
41 this.classNodes = new Vector<ClassNode>();
42 this.scheduleEdges = new Vector<ScheduleEdge>();
43 this.classNodes.add(cn);
44 this.addEdge(cn.getEdgeVector());
45 this.executionTime = -1;
56 public void setCid(int cid) {
60 public String toString() {
61 String temp = new String("");
62 for(int i = 0; i < classNodes.size(); i++) {
63 temp += classNodes.elementAt(i).getClassDescriptor().toString() + ", ";
65 temp += getTextLabel();
69 public Vector getClassNodes() {
73 public Iterator getClassNodesIterator() {
74 if(classNodes == null) {
77 return classNodes.iterator();
80 public void resetClassNodes() {
84 public Vector getScheduleEdges() {
88 public Iterator getScheduleEdgesIterator() {
89 if(scheduleEdges == null) {
92 return scheduleEdges.iterator();
95 public void resetScheduleEdges() {
99 public int getExeTime() {
100 if(this.executionTime == -1) {
103 } catch (Exception e) {
107 return this.executionTime;
110 public void calExeTime() throws Exception {
111 if(this.classNodes.size() != 1) {
112 throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
114 ClassNode cn = this.classNodes.elementAt(0);
116 throw new Error("Error: Non-sorted ClassNode!");
118 this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
121 /** Tests for equality of two flagstate objects.
124 public boolean equals(Object o) {
125 if (o instanceof ScheduleNode) {
126 ScheduleNode fs=(ScheduleNode)o;
127 if(fs.gid == this.gid) {
128 if(fs.uid != this.uid) {
131 if(fs.cid != this.cid) {
135 if ((fs.executionTime != this.executionTime)){
138 if(fs.classNodes != null) {
139 if(!fs.classNodes.equals(classNodes)) {
142 } else if(classNodes != null) {
150 public int hashCode() {
151 int hashcode = gid^uid^cid^executionTime;
152 if(this.classNodes != null) {
153 hashcode ^= classNodes.hashCode();
158 public String getLabel() {
159 return "cluster" + uid;
162 public String getTextLabel() {
170 public Object clone(Hashtable<ClassNode, ClassNode> cn2cn, int gid) {
171 ScheduleNode o = null;
173 o = (ScheduleNode) super.clone();
174 } catch(CloneNotSupportedException e){
177 o.uid = ScheduleNode.nodeID++;
180 // Clone all the internal ClassNodes and ScheduleEdges
181 Vector<ClassNode> tcns = new Vector<ClassNode>();
182 Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
184 for(i = 0; i < this.classNodes.size(); i++) {
185 ClassNode tcn = this.classNodes.elementAt(i);
186 ClassNode cn = (ClassNode)tcn.clone();
187 cn.setScheduleNode(o);
191 for(i = 0; i < this.scheduleEdges.size(); i++) {
192 ScheduleEdge temp = this.scheduleEdges.elementAt(i);
193 ScheduleEdge se = null;
194 switch(temp.getType()) {
195 case ScheduleEdge.NEWEDGE: {
196 se = new ScheduleEdge(o, "new", temp.getFstate(), ScheduleEdge.NEWEDGE, gid);
197 se.setProbability(temp.getProbability());
198 se.setNewRate(temp.getNewRate());
202 case ScheduleEdge.TRANSEDGE: {
203 se = new ScheduleEdge(o, "transmit", temp.getFstate(), ScheduleEdge.TRANSEDGE, gid);
204 se.setProbability(temp.getProbability());
205 se.setNewRate(temp.getNewRate());
209 se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
210 se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
211 se.setTransTime(temp.getTransTime());
212 se.setFEdge(temp.getFEdge());
213 se.setTargetFState(temp.getTargetFState());
218 o.scheduleEdges = tses;
222 o.inedges = new Vector();
223 o.edges = new Vector();
227 public void mergeSEdge(ScheduleEdge se) throws Exception {
228 ScheduleNode sn = (ScheduleNode)se.getTarget();
229 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
230 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
232 for(int i = 0; i < targetCNodes.size(); i++) {
233 targetCNodes.elementAt(i).setScheduleNode(this);
236 if(classNodes == null) {
237 classNodes = targetCNodes;
238 scheduleEdges = targetSEdges;
240 if(targetCNodes.size() != 0) {
241 classNodes.addAll(targetCNodes);
243 if(targetSEdges.size() != 0) {
244 scheduleEdges.addAll(targetSEdges);
249 if(ScheduleEdge.TRANSEDGE == se.getType()) {
253 // merge the split ClassNode of same class
254 FlagState sfs = se.getFstate();
255 FlagState tfs = se.getTargetFState();
256 ClassNode scn = se.getSourceCNode();
257 ClassNode tcn = se.getTargetCNode();
258 sfs.getEdgeVector().addAll(tfs.getEdgeVector());
259 // merge the subtree whose root is nfs from the whole flag transition tree
260 Vector<FlagState> sfss = scn.getFlagStates();
261 sfss.addAll(tcn.getFlagStates());
262 sfss.removeElement(tfs);
263 classNodes.removeElement(tcn);
265 // flush the exeTime of fs and its ancestors
267 Queue<FlagState> toiterate = new LinkedList<FlagState>();
269 while(!toiterate.isEmpty()) {
270 FlagState tmpfs = toiterate.poll();
271 int ttime = tmpfs.getExeTime();
272 Iterator it_inedges = tmpfs.inedges();
273 while(it_inedges.hasNext()) {
274 FEdge fEdge = (FEdge)it_inedges.next();
275 FlagState temp = (FlagState)fEdge.getSource();
276 int time = fEdge.getExeTime() + ttime;
277 if(temp.getExeTime() > time) {
278 temp.setExeTime(time);
285 // redirct internal ScheduleEdge from tcn to scn
286 for(int i = 0; i < targetSEdges.size(); ++i) {
287 ScheduleEdge tmpse = targetSEdges.elementAt(i);
288 if(tmpse.getSourceCNode().equals(tcn)) {
289 tmpse.setSourceCNode(scn);
293 // redirect external ScheduleEdges to this ScheduleNode
294 // and scn if it is originally from tcn
295 Iterator it_edges = sn.edges();
296 while(it_edges.hasNext()) {
297 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
299 if(tse.getSourceCNode().equals(tcn)) {
300 tse.setSourceCNode(scn);
302 this.edges.addElement(tse);
307 // As all tasks inside one ScheduleNode are executed sequentially,
308 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
309 if(this.executionTime == -1) {
310 throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
312 if(this.executionTime < sn.getExeTime()) {
313 this.executionTime = sn.getExeTime();
315 } else if(ScheduleEdge.NEWEDGE == se.getType()) {
318 scheduleEdges.add(se);
319 se.resetListExeTime();
322 Iterator it_edges = sn.edges();
323 while(it_edges.hasNext()) {
324 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
326 this.edges.addElement(tse);
329 // As all tasks inside one ScheduleNode are executed sequentially,
330 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
331 if(this.executionTime == -1) {
332 this.executionTime = 0;
334 this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
338 public void mergeSNode(ScheduleNode sn) throws Exception {
339 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
340 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
342 for(int i = 0; i < targetCNodes.size(); i++) {
343 targetCNodes.elementAt(i).setScheduleNode(this);
346 if(classNodes == null) {
347 classNodes = targetCNodes;
348 scheduleEdges = targetSEdges;
350 if(targetCNodes.size() != 0) {
351 classNodes.addAll(targetCNodes);
353 if(targetSEdges.size() != 0) {
354 scheduleEdges.addAll(targetSEdges);
360 // redirect external ScheduleEdges to this ScheduleNode
361 Iterator it_edges = sn.edges();
362 while(it_edges.hasNext()) {
363 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
365 this.edges.addElement(tse);
368 it_edges = sn.inedges();
369 while(it_edges.hasNext()) {
370 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
372 this.inedges.addElement(tse);
375 // As all tasks inside one ScheduleNode are executed sequentially,
376 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
377 if(this.executionTime == -1) {
378 this.executionTime = 0;
380 this.executionTime += sn.getExeTime();