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 if(!temp.getIsNew()) {
179 se = new ScheduleEdge(o, "transmit",temp.getFstate(), false, gid);//new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false, gid);
181 se = new ScheduleEdge(o, "new",temp.getFstate(), gid);//new ScheduleEdge(o, "new",temp.getClassDescriptor(), gid);
183 se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
184 se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
185 se.setProbability(temp.getProbability());
186 se.setNewRate(temp.getNewRate());
187 se.setTransTime(temp.getTransTime());
188 se.setFEdge(temp.getFEdge());
189 se.setTargetFState(temp.getTargetFState());
194 o.scheduleEdges = tses;
197 o.inedges = new Vector();
198 o.edges = new Vector();
203 public void mergeSEdge(ScheduleEdge se) {
204 assert(se.getIsNew());
206 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)((ScheduleNode)se.getTarget()).getClassNodes();
207 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)((ScheduleNode)se.getTarget()).getScheduleEdges();
209 for(int i = 0; i < targetCNodes.size(); i++) {
210 targetCNodes.elementAt(i).setScheduleNode(this);
213 if(classNodes == null) {
214 classNodes = targetCNodes;
215 scheduleEdges = targetSEdges;
217 if(targetCNodes.size() != 0) {
218 classNodes.addAll(targetCNodes);
220 if(targetSEdges.size() != 0) {
221 scheduleEdges.addAll(targetSEdges);
227 scheduleEdges.add(se);
228 se.resetListExeTime();
229 se.getTarget().removeInedge(se);
231 Iterator it_edges = se.getTarget().edges();
232 while(it_edges.hasNext()) {
233 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
235 this.edges.addElement(tse);
238 // As all tasks inside one ScheduleNode are executed sequentially,
239 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
240 if(this.executionTime == -1) {
241 this.executionTime = 0;
243 this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
246 public void mergeTransEdge(ScheduleEdge se) throws Exception {
247 ScheduleNode sn = (ScheduleNode)se.getTarget();
248 Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
249 Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
251 for(int i = 0; i < targetCNodes.size(); i++) {
252 targetCNodes.elementAt(i).setScheduleNode(this);
255 if(classNodes == null) {
256 classNodes = targetCNodes;
257 scheduleEdges = targetSEdges;
259 if(targetCNodes.size() != 0) {
260 classNodes.addAll(targetCNodes);
262 if(targetSEdges.size() != 0) {
263 scheduleEdges.addAll(targetSEdges);
270 Iterator it_edges = sn.edges();
271 while(it_edges.hasNext()) {
272 ScheduleEdge tse = (ScheduleEdge)it_edges.next();
274 this.edges.addElement(tse);
277 // merge the split ClassNode of same class
278 FlagState sfs = se.getFstate();
279 FlagState tfs = se.getTargetFState();
280 ClassNode scn = se.getSourceCNode();
281 ClassNode tcn = se.getTargetCNode();
282 sfs.getEdgeVector().addAll(tfs.getEdgeVector());
283 // merge the subtree whose root is nfs from the whole flag transition tree
284 Vector<FlagState> sfss = scn.getFlagStates();
285 sfss.addAll(tcn.getFlagStates());
286 sfss.removeElement(tfs);
287 classNodes.removeElement(tcn);
289 // flush the exeTime of fs and its ancestors
291 Queue<FlagState> toiterate = new LinkedList<FlagState>();
293 while(!toiterate.isEmpty()) {
294 FlagState tmpfs = toiterate.poll();
295 int ttime = tmpfs.getExeTime();
296 Iterator it_inedges = tmpfs.inedges();
297 while(it_inedges.hasNext()) {
298 FEdge fEdge = (FEdge)it_inedges.next();
299 FlagState temp = (FlagState)fEdge.getSource();
300 int time = fEdge.getExeTime() + ttime;
301 if(temp.getExeTime() > time) {
302 temp.setExeTime(time);
309 // redirct internal ScheduleEdge from tcn to scn
310 for(int i = 0; i < targetSEdges.size(); ++i) {
311 ScheduleEdge tmpse = targetSEdges.elementAt(i);
312 if(tmpse.getSourceCNode().equals(tcn)) {
313 tmpse.setSourceCNode(scn);
318 // As all tasks inside one ScheduleNode are executed sequentially,
319 // simply add the execution time of all the ClassNodes inside one ScheduleNode.
320 if(this.executionTime == -1) {
321 throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
323 if(this.executionTime < sn.getExeTime()) {
324 this.executionTime = sn.getExeTime();