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{
15 private static int nodeID=0;
17 private Vector<ClassNode> classNodes;
18 Vector<ScheduleEdge> scheduleEdges;
19 private Vector<ScheduleEdge> associateEdges;
20 private Vector<ScheduleEdge> inassociateEdges;
22 private int executionTime;
25 * @param cd ClassDescriptor
28 public ScheduleNode(int gid) {
29 this.uid = ScheduleNode.nodeID++;
31 this.executionTime = -1;
32 this.classNodes = null;
33 this.scheduleEdges = null;
34 this.associateEdges = new Vector<ScheduleEdge>();
35 this.inassociateEdges = new Vector<ScheduleEdge>();
38 public ScheduleNode(ClassNode cn, int gid) {
39 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;
46 this.associateEdges = new Vector<ScheduleEdge>();
47 this.inassociateEdges = new Vector<ScheduleEdge>();
54 public String toString() {
55 String temp = new String("");
56 for(int i = 0; i < classNodes.size(); i++) {
57 temp += classNodes.elementAt(i).getClassDescriptor().toString() + ", ";
59 temp += getTextLabel();
63 public Vector getClassNodes() {
67 public Iterator getClassNodesIterator() {
68 if(classNodes == null) {
71 return classNodes.iterator();
74 public void resetClassNodes() {
78 public Vector getScheduleEdges() {
82 public Iterator getScheduleEdgesIterator() {
83 if(scheduleEdges == null) {
86 return scheduleEdges.iterator();
89 public void resetScheduleEdges() {
93 public Vector getAssociateSEdges() {
94 return this.associateEdges;
97 public Iterator getAssociateSEdgesIterator() {
98 return this.associateEdges.iterator();
101 public void addAssociateSEdge(ScheduleEdge se) {
102 assert(ScheduleEdge.ASSOCEDGE == se.getType());
104 this.associateEdges.addElement(se);
106 ScheduleNode tonode=(ScheduleNode)se.getTarget();
107 tonode.addInAssociateSEdge(se);
110 public Vector getInAssociateSEdges() {
111 return this.inassociateEdges;
114 public Iterator getInAssociateSEdgesIterator() {
115 return this.inassociateEdges.iterator();
118 public void addInAssociateSEdge(ScheduleEdge se) {
119 assert(ScheduleEdge.ASSOCEDGE == se.getType());
121 this.inassociateEdges.addElement(se);
124 public int getExeTime() {
125 if(this.executionTime == -1) {
128 } catch (Exception e) {
132 return this.executionTime;
135 public void calExeTime() throws Exception {
136 if(this.classNodes.size() != 1) {
137 throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
139 ClassNode cn = this.classNodes.elementAt(0);
141 throw new Error("Error: Non-sorted ClassNode!");
143 this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
146 /** Tests for equality of two flagstate objects.
149 public boolean equals(Object o) {
150 if (o instanceof ScheduleNode) {
151 ScheduleNode fs=(ScheduleNode)o;
152 if(fs.gid == this.gid) {
153 if(fs.uid != this.uid) {
157 if ((fs.executionTime != this.executionTime)){
160 if(fs.classNodes != null) {
161 if(!fs.classNodes.equals(classNodes)) {
164 } else if(classNodes != null) {
172 public int hashCode() {
173 int hashcode = gid^uid^executionTime;
174 if(this.classNodes != null) {
175 hashcode ^= classNodes.hashCode();
180 public String getLabel() {
181 return "cluster" + uid;
184 public String getTextLabel() {
192 public Object clone(Hashtable<ClassNode, ClassNode> cn2cn, int gid) {
193 ScheduleNode o = null;
195 o = (ScheduleNode)super.clone();
196 } catch(CloneNotSupportedException e){
199 o.uid = ScheduleNode.nodeID++;
201 // Clone all the internal ClassNodes and ScheduleEdges
202 Vector<ClassNode> tcns = new Vector<ClassNode>();
203 Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
205 for(i = 0; i < this.classNodes.size(); i++) {
206 ClassNode tcn = this.classNodes.elementAt(i);
207 ClassNode cn = (ClassNode)tcn.clone();
208 cn.setScheduleNode(o);
212 for(i = 0; i < this.scheduleEdges.size(); i++) {
213 ScheduleEdge temp = this.scheduleEdges.elementAt(i);
214 ScheduleEdge se = null;
215 switch(temp.getType()) {
216 case ScheduleEdge.NEWEDGE: {
217 se = new ScheduleEdge(o, "new", temp.getFstate(), ScheduleEdge.NEWEDGE, gid);
218 se.setProbability(temp.getProbability());
219 se.setNewRate(temp.getNewRate());
222 case ScheduleEdge.TRANSEDGE: {
223 se = new ScheduleEdge(o, "transmit", temp.getFstate(), ScheduleEdge.TRANSEDGE, gid);
224 se.setProbability(temp.getProbability());
225 se.setNewRate(temp.getNewRate());
228 case ScheduleEdge.ASSOCEDGE: {
230 se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
234 se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
235 se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
236 se.setTransTime(temp.getTransTime());
237 se.setFEdge(temp.getFEdge());
238 se.setTargetFState(temp.getTargetFState());
243 o.scheduleEdges = tses;
247 /*Vector<ScheduleEdge> assses = new Vector<ScheduleEdge>();
248 for(i = 0; i < this.scheduleEdges.size(); i++) {
249 ScheduleEdge temp = this.scheduleEdges.elementAt(i);
251 assert(ScheduleEdge.ASSOCEDGE == temp.getType());
252 ScheduleEdge se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
253 se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
254 se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
255 se.setTransTime(temp.getTransTime());
256 se.setFEdge(temp.getFEdge());
257 se.setTargetFState(temp.getTargetFState());
261 o.associateEdges = assses;
264 Vector<ScheduleEdge> assses = new Vector<ScheduleEdge>();
265 for(i = 0; i < this.scheduleEdges.size(); i++) {
266 ScheduleEdge temp = this.scheduleEdges.elementAt(i);
268 assert(ScheduleEdge.ASSOCEDGE == temp.getType());
269 ScheduleEdge se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
270 se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
271 se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
272 se.setTransTime(temp.getTransTime());
273 se.setFEdge(temp.getFEdge());
274 se.setTargetFState(temp.getTargetFState());
278 o.associateEdges = assses;
281 o.inedges = new Vector();
282 o.edges = new Vector();
283 o.associateEdges = new Vector<ScheduleEdge>();
284 o.inassociateEdges = new Vector<ScheduleEdge>();
288 public void mergeSEdge(ScheduleEdge se) throws Exception {
289 ScheduleNode sn = (ScheduleNode)se.getTarget();
290 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
291 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
293 for(int i = 0; i < targetCNodes.size(); i++) {
294 targetCNodes.elementAt(i).setScheduleNode(this);
297 if(classNodes == null) {
298 classNodes = targetCNodes;
299 scheduleEdges = targetSEdges;
301 if(targetCNodes.size() != 0) {
302 classNodes.addAll(targetCNodes);
304 if(targetSEdges.size() != 0) {
305 scheduleEdges.addAll(targetSEdges);
310 if(ScheduleEdge.TRANSEDGE == se.getType()) {
314 // merge the split ClassNode of same class
315 FlagState sfs = se.getFstate();
316 FlagState tfs = se.getTargetFState();
317 ClassNode scn = se.getSourceCNode();
318 ClassNode tcn = se.getTargetCNode();
319 sfs.getEdgeVector().addAll(tfs.getEdgeVector());
320 // merge the subtree whose root is nfs from the whole flag transition tree
321 Vector<FlagState> sfss = scn.getFlagStates();
322 sfss.addAll(tcn.getFlagStates());
323 sfss.removeElement(tfs);
324 classNodes.removeElement(tcn);
326 // flush the exeTime of fs and its ancestors
328 Queue<FlagState> toiterate = new LinkedList<FlagState>();
330 while(!toiterate.isEmpty()) {
331 FlagState tmpfs = toiterate.poll();
332 int ttime = tmpfs.getExeTime();
333 Iterator it_inedges = tmpfs.inedges();
334 while(it_inedges.hasNext()) {
335 FEdge fEdge = (FEdge)it_inedges.next();
336 FlagState temp = (FlagState)fEdge.getSource();
337 int time = fEdge.getExeTime() + ttime;
338 if(temp.getExeTime() > time) {
339 temp.setExeTime(time);
346 // redirct internal ScheduleEdge from tcn to scn
347 for(int i = 0; i < targetSEdges.size(); ++i) {
348 ScheduleEdge tmpse = targetSEdges.elementAt(i);
349 if(tmpse.getSourceCNode().equals(tcn)) {
350 tmpse.setSourceCNode(scn);
354 // redirect external ScheduleEdges to this ScheduleNode
355 // and scn if it is originally from tcn
356 Iterator it_edges = sn.edges();
357 while(it_edges.hasNext()) {
358 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
360 if(tse.getSourceCNode().equals(tcn)) {
361 tse.setSourceCNode(scn);
363 this.edges.addElement(tse);
368 // As all tasks inside one ScheduleNode are executed sequentially,
369 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
370 if(this.executionTime == -1) {
371 throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
373 if(this.executionTime < sn.getExeTime()) {
374 this.executionTime = sn.getExeTime();
376 } else if(ScheduleEdge.NEWEDGE == se.getType()) {
379 scheduleEdges.add(se);
380 se.resetListExeTime();
383 Iterator it_edges = sn.edges();
384 while(it_edges.hasNext()) {
385 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
387 this.edges.addElement(tse);
390 // As all tasks inside one ScheduleNode are executed sequentially,
391 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
392 if(this.executionTime == -1) {
393 this.executionTime = 0;
395 this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();