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;
20 private int executionTime;
23 * @param cd ClassDescriptor
26 public ScheduleNode(int gid) {
27 this.uid = ScheduleNode.nodeID++;
29 this.executionTime = -1;
30 this.classNodes = null;
31 this.scheduleEdges = null;
34 public ScheduleNode(ClassNode cn, int gid) {
35 this.uid = ScheduleNode.nodeID++;
37 this.classNodes = new Vector<ClassNode>();
38 this.scheduleEdges = new Vector<ScheduleEdge>();
39 this.classNodes.add(cn);
40 this.addEdge(cn.getEdgeVector());
41 this.executionTime = -1;
48 public String toString() {
49 String temp = new String("");
50 for(int i = 0; i < classNodes.size(); i++) {
51 temp += classNodes.elementAt(i).getClassDescriptor().toString() + ", ";
53 temp += getTextLabel();
57 public Vector getClassNodes() {
61 public Iterator getClassNodesIterator() {
62 if(classNodes == null) {
65 return classNodes.iterator();
68 public void resetClassNodes() {
72 public Vector getScheduleEdges() {
76 public Iterator getScheduleEdgesIterator() {
77 if(scheduleEdges == null) {
80 return scheduleEdges.iterator();
83 public void resetScheduleEdges() {
87 public int getExeTime() {
88 if(this.executionTime == -1) {
91 } catch (Exception e) {
95 return this.executionTime;
98 public void calExeTime() throws Exception {
99 if(this.classNodes.size() != 1) {
100 throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
102 ClassNode cn = this.classNodes.elementAt(0);
104 throw new Error("Error: Non-sorted ClassNode!");
106 this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
109 /** Tests for equality of two flagstate objects.
112 public boolean equals(Object o) {
113 if (o instanceof ScheduleNode) {
114 ScheduleNode fs=(ScheduleNode)o;
115 if(fs.gid == this.gid) {
116 if(fs.uid != this.uid) {
120 if ((fs.executionTime != this.executionTime)){
123 if(fs.classNodes != null) {
124 if(!fs.classNodes.equals(classNodes)) {
127 } else if(classNodes != null) {
135 public int hashCode() {
136 int hashcode = gid^uid^executionTime;
137 if(this.classNodes != null) {
138 hashcode ^= classNodes.hashCode();
143 public String getLabel() {
144 return "cluster" + uid;
147 public String getTextLabel() {
155 public Object clone(Hashtable<ClassNode, ClassNode> cn2cn, int gid) {
156 ScheduleNode o = null;
158 o = (ScheduleNode)super.clone();
159 } catch(CloneNotSupportedException e){
162 o.uid = ScheduleNode.nodeID++;
164 // Clone all the internal ClassNodes and ScheduleEdges
165 Vector<ClassNode> tcns = new Vector<ClassNode>();
166 Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
168 for(i = 0; i < this.classNodes.size(); i++) {
169 ClassNode tcn = this.classNodes.elementAt(i);
170 ClassNode cn = (ClassNode)tcn.clone();
171 cn.setScheduleNode(o);
175 for(i = 0; i < this.scheduleEdges.size(); i++) {
176 ScheduleEdge temp = this.scheduleEdges.elementAt(i);
177 ScheduleEdge se = null;
178 switch(temp.getType()) {
179 case ScheduleEdge.NEWEDGE: {
180 se = new ScheduleEdge(o, "new", temp.getFstate(), ScheduleEdge.NEWEDGE, gid);
181 se.setProbability(temp.getProbability());
182 se.setNewRate(temp.getNewRate());
185 case ScheduleEdge.TRANSEDGE: {
186 se = new ScheduleEdge(o, "transmit", temp.getFstate(), ScheduleEdge.TRANSEDGE, gid);
187 se.setProbability(temp.getProbability());
188 se.setNewRate(temp.getNewRate());
192 se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
193 se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
194 se.setTransTime(temp.getTransTime());
195 se.setFEdge(temp.getFEdge());
196 se.setTargetFState(temp.getTargetFState());
201 o.scheduleEdges = tses;
205 o.inedges = new Vector();
206 o.edges = new Vector();
210 public void mergeSEdge(ScheduleEdge se) throws Exception {
211 ScheduleNode sn = (ScheduleNode)se.getTarget();
212 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
213 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
215 for(int i = 0; i < targetCNodes.size(); i++) {
216 targetCNodes.elementAt(i).setScheduleNode(this);
219 if(classNodes == null) {
220 classNodes = targetCNodes;
221 scheduleEdges = targetSEdges;
223 if(targetCNodes.size() != 0) {
224 classNodes.addAll(targetCNodes);
226 if(targetSEdges.size() != 0) {
227 scheduleEdges.addAll(targetSEdges);
232 if(ScheduleEdge.TRANSEDGE == se.getType()) {
236 // merge the split ClassNode of same class
237 FlagState sfs = se.getFstate();
238 FlagState tfs = se.getTargetFState();
239 ClassNode scn = se.getSourceCNode();
240 ClassNode tcn = se.getTargetCNode();
241 sfs.getEdgeVector().addAll(tfs.getEdgeVector());
242 // merge the subtree whose root is nfs from the whole flag transition tree
243 Vector<FlagState> sfss = scn.getFlagStates();
244 sfss.addAll(tcn.getFlagStates());
245 sfss.removeElement(tfs);
246 classNodes.removeElement(tcn);
248 // flush the exeTime of fs and its ancestors
250 Queue<FlagState> toiterate = new LinkedList<FlagState>();
252 while(!toiterate.isEmpty()) {
253 FlagState tmpfs = toiterate.poll();
254 int ttime = tmpfs.getExeTime();
255 Iterator it_inedges = tmpfs.inedges();
256 while(it_inedges.hasNext()) {
257 FEdge fEdge = (FEdge)it_inedges.next();
258 FlagState temp = (FlagState)fEdge.getSource();
259 int time = fEdge.getExeTime() + ttime;
260 if(temp.getExeTime() > time) {
261 temp.setExeTime(time);
268 // redirct internal ScheduleEdge from tcn to scn
269 for(int i = 0; i < targetSEdges.size(); ++i) {
270 ScheduleEdge tmpse = targetSEdges.elementAt(i);
271 if(tmpse.getSourceCNode().equals(tcn)) {
272 tmpse.setSourceCNode(scn);
276 // redirect external ScheduleEdges to this ScheduleNode
277 // and scn if it is originally from tcn
278 Iterator it_edges = sn.edges();
279 while(it_edges.hasNext()) {
280 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
282 if(tse.getSourceCNode().equals(tcn)) {
283 tse.setSourceCNode(scn);
285 this.edges.addElement(tse);
290 // As all tasks inside one ScheduleNode are executed sequentially,
291 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
292 if(this.executionTime == -1) {
293 throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
295 if(this.executionTime < sn.getExeTime()) {
296 this.executionTime = sn.getExeTime();
298 } else if(ScheduleEdge.NEWEDGE == se.getType()) {
301 scheduleEdges.add(se);
302 se.resetListExeTime();
305 Iterator it_edges = sn.edges();
306 while(it_edges.hasNext()) {
307 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
309 this.edges.addElement(tse);
312 // As all tasks inside one ScheduleNode are executed sequentially,
313 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
314 if(this.executionTime == -1) {
315 this.executionTime = 0;
317 this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();