Add new feature of splitting nodes into Scheduling algorithm and fix some bugs in...
authorjzhou <jzhou>
Wed, 16 Jan 2008 23:46:19 +0000 (23:46 +0000)
committerjzhou <jzhou>
Wed, 16 Jan 2008 23:46:19 +0000 (23:46 +0000)
Robust/src/Analysis/Scheduling/ClassNode.java
Robust/src/Analysis/Scheduling/ScheduleAnalysis.java
Robust/src/Analysis/Scheduling/ScheduleEdge.java
Robust/src/Analysis/Scheduling/ScheduleNode.java
Robust/src/Analysis/TaskStateAnalysis/FEdge.java
Robust/src/Analysis/TaskStateAnalysis/FlagState.java

index 027d8dd615e63cf6208676c11c2802984ffd65be..9964ecf8996bdb276b82e83da677c1467dfcd465 100644 (file)
@@ -17,6 +17,9 @@ public class ClassNode extends GraphNode implements Cloneable{
     private ScheduleNode sn;
     private Vector<FlagState> flagStates;
     private boolean sorted = false;
+    private boolean clone = false;
+    
+    private int transTime;
 
     /** Class constructor
      * @param cd ClassDescriptor
@@ -27,6 +30,15 @@ public class ClassNode extends GraphNode implements Cloneable{
        this.flagStates = fStates;
        this.sn = null;
        this.uid=ClassNode.nodeID++;
+       this.transTime = 0;
+    }
+    
+    public int getTransTime() {
+       return this.transTime;
+    }
+    
+    public void setTransTime(int transTime) {
+       this.transTime = transTime;
     }
    
     public int getuid() {
@@ -53,6 +65,10 @@ public class ClassNode extends GraphNode implements Cloneable{
        return flagStates;
     }
     
+    public boolean isclone() {
+       return clone;
+    }
+    
     public String toString() {
        return cd.toString()+getTextLabel();
     }
@@ -84,7 +100,9 @@ public class ClassNode extends GraphNode implements Cloneable{
            ClassNode fs=(ClassNode)o;
             if ((fs.getClassDescriptor()!= cd) || 
                (fs.getScheduleNode() != sn) || 
-               (fs.isSorted() != sorted)) {
+               (fs.isSorted() != sorted) ||
+               (fs.clone != this.clone) ||
+               (fs.transTime != this.transTime)) {
                 return false;
             }
            return (fs.getFlagStates().equals(flagStates));
@@ -121,6 +139,13 @@ public class ClassNode extends GraphNode implements Cloneable{
            e.printStackTrace();
        }
        o.uid = ClassNode.nodeID++;
+       o.clone = true;
        return o;
     }
+    
+    public void calExeTime() {
+       for(int i = 0; i <  this.flagStates.size(); i++) {
+           this.flagStates.elementAt(i).getExeTime();
+       }
+    }
 }
index e3423ebebc3b54562e719c61b798b491a6846516..b31b59871d9300fb3ebdc7ef1a55e611816c3c15 100644 (file)
@@ -1,7 +1,9 @@
 package Analysis.Scheduling;
 
 import Analysis.TaskStateAnalysis.*;
+import Analysis.TaskStateAnalysis.FEdge.NewObjInfo;
 import IR.*;
+
 import java.util.*;
 import java.io.*;
 
@@ -17,11 +19,11 @@ public class ScheduleAnalysis {
     State state;
     Vector<ScheduleNode> scheduleNodes;
     Vector<ClassNode> classNodes;
+    Hashtable<ClassDescriptor, ClassNode> cd2ClassNode;
     boolean sorted = false;
     Vector<ScheduleEdge> scheduleEdges;
-    Hashtable<TaskDescriptor, Hashtable<ClassDescriptor, Vector<ScheduleEdge>>> taskToSEdges;
-    
-    int probabilityThreshold;
+
+    int transThreshold;
 
     public ScheduleAnalysis(State state, TaskAnalysis taskanalysis) {
        this.state = state;
@@ -29,16 +31,13 @@ public class ScheduleAnalysis {
        this.scheduleNodes = new Vector<ScheduleNode>();
        this.classNodes = new Vector<ClassNode>();
        this.scheduleEdges = new Vector<ScheduleEdge>();
-       this.taskToSEdges = new Hashtable<TaskDescriptor, Hashtable<ClassDescriptor, Vector<ScheduleEdge>>>();
-       this.probabilityThreshold = 45;
+       this.cd2ClassNode = new Hashtable<ClassDescriptor, ClassNode>();
+
+       this.transThreshold = 45;
     } 
     
-    public void setProbabilityThreshold(int pt) {
-       this.probabilityThreshold = pt;
-    }
-    
-    public Vector<ScheduleEdge> getSEdges(TaskDescriptor td, ClassDescriptor cd) {
-       return taskToSEdges.get(td).get(cd);
+    public void setTransThreshold(int tt) {
+       this.transThreshold = tt;
     }
     
     public Vector<ScheduleEdge> getSEdges4Test() {
@@ -61,8 +60,15 @@ public class ScheduleAnalysis {
                ClassNode cNode = new ClassNode(cd, sFStates);
                cNode.setSorted(true);
                classNodes.add(cNode);
+               cd2ClassNode.put(cd, cNode);
                cdToCNodes.put(cd, cNode);
-          }    
+               cNode.calExeTime();
+               
+               // for test
+               if(cd.getSymbol().equals("C")) {
+                   cNode.setTransTime(45);
+               }
+           }    
        }
 
        // For each ClassNode create a ScheduleNode containing it
@@ -71,6 +77,11 @@ public class ScheduleAnalysis {
            ScheduleNode sn = new ScheduleNode(classNodes.elementAt(i));
            classNodes.elementAt(i).setScheduleNode(sn);
            scheduleNodes.add(sn);
+           try {
+               sn.calExeTime();
+           } catch (Exception e) {
+               e.printStackTrace();
+           }
        }
        
        // Create 'new' edges between the ScheduleNodes.
@@ -91,24 +102,24 @@ public class ScheduleAnalysis {
                            ScheduleNode sNode = cNode.getScheduleNode();
                            for(int j = 0; j < numEdges; j++) {
                                FEdge pfe = fev.elementAt(j);
+                               FEdge.NewObjInfo noi = pfe.getNewObjInfo(cd);
+                               if ((noi == null) || (noi.getNewRate() == 0) || (noi.getProbability() == 0)) {
+                                   // fake creating edge, do not need to create corresponding 'new' edge
+                                   continue;
+                               }
                                FlagState pfs = (FlagState)pfe.getTarget();
                                ClassDescriptor pcd = pfs.getClassDescriptor();
                                ClassNode pcNode = cdToCNodes.get(pcd);
-                                               
-                               ScheduleEdge sEdge = new ScheduleEdge(sNode, "new", td, cd);
+                               
+                               ScheduleEdge sEdge = new ScheduleEdge(sNode, "new",/* td,*/ cd);
                                sEdge.setFEdge(pfe);
                                sEdge.setSourceCNode(pcNode);
                                sEdge.setTargetCNode(cNode);
                                sEdge.setTargetFState(root);
+                               sEdge.setNewRate(noi.getNewRate());
+                               sEdge.setProbability(noi.getProbability());
                                pcNode.getScheduleNode().addEdge(sEdge);
                                scheduleEdges.add(sEdge);
-                               if(taskToSEdges.get(td) == null) {
-                                   taskToSEdges.put(td, new Hashtable<ClassDescriptor, Vector<ScheduleEdge>>());
-                               }
-                               if(taskToSEdges.get(td).get(cd) == null)  {
-                                   taskToSEdges.get(td).put(cd, new Vector<ScheduleEdge>());
-                               }
-                               taskToSEdges.get(td).get(cd).add(sEdge);
                                if((j !=0 ) || (k != 0) || (h != 0)) {
                                    toBreakDown.add(sEdge);
                                }
@@ -137,71 +148,253 @@ public class ScheduleAnalysis {
        for(i = 0; i < toBreakDown.size(); i++ ) {
            cloneSNodeList(toBreakDown.elementAt(i), false);
        }
+       
+       // Remove fake 'new' edges
+       for(i = 0; i < scheduleEdges.size(); i++) {
+           ScheduleEdge se = scheduleEdges.elementAt(i);
+           if((0 == se.getNewRate()) || (0 == se.getProbability())) {
+               scheduleEdges.removeElement(se);
+               scheduleNodes.removeElement(se.getTarget());
+           }
+       }
     }
     
+    /*private void removeSNodeList(ScheduleEdge se) {
+       ScheduleNode sNode = (ScheduleNode)se.getTarget();
+       scheduleNodes.removeElement(sNode);
+       Vector<ClassNode> cNodes = sNode.getClassNodes();
+       for(int i = 0; i < cNodes.size(); i++) {
+           classNodes.removeElement(cNodes.elementAt(i));
+           cd2ClassNode.remove(cNodes.elementAt(i).getClassDescriptor());
+       }
+       Vector<ScheduleEdge> edges = sNode.getEdgeVector();
+        for(int j = 0; j < edges.size(); j++) {
+            removeSNodeList(edges.elementAt(j));
+        }
+    }*/
+    
     public void scheduleAnalysis() {
        // First iteration
-       int i = 0;      
-       Vector<ScheduleEdge> rsev = new Vector<ScheduleEdge>();
+       int i = 0; 
+       //Access the ScheduleEdges in reverse topology order
+       Hashtable<FEdge, Vector<ScheduleEdge>> fe2ses = new Hashtable<FEdge, Vector<ScheduleEdge>>();
+       Hashtable<ScheduleNode, Vector<FEdge>> sn2fes = new Hashtable<ScheduleNode, Vector<FEdge>>();
+       ScheduleNode preSNode = null;
        for(i = scheduleEdges.size(); i > 0; i--) {
            ScheduleEdge se = scheduleEdges.elementAt(i-1);
-           if(!(se.getProbability() > this.probabilityThreshold)){
-               // Merge the target ScheduleNode into the source ScheduleNode
-               ((ScheduleNode)se.getSource()).merge(se);
-               scheduleNodes.remove(se.getTarget());
-               se.setTarget((ScheduleNode)se.getSource());
-               rsev.add(se);
+           if(preSNode == null) {
+               preSNode = (ScheduleNode)se.getSource();
+           }
+           if(se.getIsNew()) {
+               boolean split = false;
+               FEdge fe = se.getFEdge();
+               if(fe.getSource() == fe.getTarget()) {
+                   // back edge
+                   int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
+                   int rate = 0;
+                   if(repeat > 1){
+                       for(int j = 1; j< repeat; j++ ) {
+                           cloneSNodeList(se, true);
+                       }
+                       se.setNewRate(1);
+                       se.setProbability(100);
+                   }  
+                   try {
+                       rate = (int)Math.ceil(se.getListExeTime()/ calInExeTime(se.getSourceFState()));
+                   } catch (Exception e) {
+                       e.printStackTrace();
+                   }
+                   for(int j = rate - 1; j > 0; j--) {
+                       for(int k = repeat; k > 0; k--) {
+                           cloneSNodeList(se, true);
+                       }
+                   }
+               } else {
+                   // if preSNode is not the same as se's source ScheduleNode
+                   // handle any ScheduleEdges previously put into fe2ses whose source ScheduleNode is preSNode
+                   boolean same = (preSNode == se.getSource());
+                   if(!same) {
+                       if(preSNode.getFinishingTime() < se.getSource().getFinishingTime()) {
+                           if(sn2fes.containsKey(preSNode)) {
+                               Vector<FEdge> fes = sn2fes.remove(preSNode);
+                               for(int j = 0; j < fes.size(); j++) {
+                                   FEdge tempfe = fes.elementAt(j);
+                                   Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
+                                   ScheduleEdge tempse = ses.elementAt(0);
+                                   int temptime = tempse.getListExeTime();
+                                   // find out the ScheduleEdge with least exeTime
+                                   for(int k = 1; k < ses.size(); k++) {
+                                       int ttemp = ses.elementAt(k).getListExeTime();
+                                       if(ttemp < temptime) {
+                                           tempse = ses.elementAt(k);
+                                           temptime = ttemp;
+                                       }
+                                   }
+                                   // handle the tempse
+                                   handleScheduleEdge(tempse, true);
+                                   ses.removeElement(tempse);
+                                   // handle other ScheduleEdges
+                                   for(int k = 0; k < ses.size(); k++) {
+                                       handleScheduleEdge(ses.elementAt(k), false);
+                                   }
+                                   ses = null;
+                                   fe2ses.remove(tempfe);
+                               }
+                               fes = null;
+                           }
+                       }
+                       preSNode = (ScheduleNode)se.getSource();
+                   }
+                   
+                   // if fe is the last task inside this ClassNode, delay the expanding and merging until we find all such 'nmew' edges
+                   // associated with a last task inside this ClassNode
+                   if(!fe.getTarget().edges().hasNext()) {
+                       if(fe2ses.get(fe) == null) {
+                           fe2ses.put(fe, new Vector<ScheduleEdge>());
+                       }
+                       if(sn2fes.get((ScheduleNode)se.getSource()) == null) {
+                           sn2fes.put((ScheduleNode)se.getSource(), new Vector<FEdge>());
+                       }
+                       fe2ses.get(fe).add(se);
+                       sn2fes.get((ScheduleNode)se.getSource()).add(fe);
+                   } else {
+                       // As this is not a last task, first handle available ScheduleEdges previously put into fe2ses
+                       if((same) && (sn2fes.containsKey(preSNode))) {
+                           Vector<FEdge> fes = sn2fes.remove(preSNode);
+                           for(int j = 0; j < fes.size(); j++) {
+                               FEdge tempfe = fes.elementAt(j);
+                               Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
+                               ScheduleEdge tempse = ses.elementAt(0);
+                               int temptime = tempse.getListExeTime();
+                               // find out the ScheduleEdge with least exeTime
+                               for(int k = 1; k < ses.size(); k++) {
+                                   int ttemp = ses.elementAt(k).getListExeTime();
+                                   if(ttemp < temptime) {
+                                       tempse = ses.elementAt(k);
+                                       temptime = ttemp;
+                                   }
+                               }
+                               // handle the tempse
+                               handleScheduleEdge(tempse, true);
+                               ses.removeElement(tempse);
+                               // handle other ScheduleEdges
+                               for(int k = 0; k < ses.size(); k++) {
+                                   handleScheduleEdge(ses.elementAt(k), false);
+                               }
+                               ses = null;
+                               fe2ses.remove(tempfe);
+                           }
+                           fes = null;
+                       }
+                       
+                       if((!(se.getTransTime() < this.transThreshold)) && (se.getSourceCNode().getTransTime() < se.getTransTime())) {
+                           split = true;
+                           splitSNode(se, true);
+                       } else {
+                           // handle this ScheduleEdge
+                           handleScheduleEdge(se, true);
+                       }
+                   }                   
+               }
            }
        }
-       scheduleEdges.removeAll(rsev);
-       rsev = null;
-       
-       //Second iteration
-       //Access the ScheduleEdges in reverse topology order
-       for(i = scheduleEdges.size(); i > 0; i--) {
-           ScheduleEdge se = scheduleEdges.elementAt(i-1);
-           FEdge fe = se.getFEdge();
-           if(fe.getSource() == fe.getTarget()) {
-               // back edge
-               if(se.getNewRate() > 1){
-                   for(int j = 1; j< se.getNewRate(); j++ ) {
-                       cloneSNodeList(se, true);
-                   }
-                   se.setNewRate(1);
+       if(!fe2ses.isEmpty()) {
+           Set<FEdge> keys = fe2ses.keySet();
+           Iterator it_keys = keys.iterator();
+           while(it_keys.hasNext()) {
+               FEdge tempfe = (FEdge)it_keys.next();
+               Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
+               ScheduleEdge tempse = ses.elementAt(0);
+               int temptime = tempse.getListExeTime();
+               // find out the ScheduleEdge with least exeTime
+               for(int k = 1; k < ses.size(); k++) {
+                   int ttemp = ses.elementAt(k).getListExeTime();
+                   if(ttemp < temptime) {
+                       tempse = ses.elementAt(k);
+                       temptime = ttemp;
+                   }
                }
+               // handle the tempse
+               handleScheduleEdge(tempse, true);
+               ses.removeElement(tempse);
+               // handle other ScheduleEdges
+               for(int k = 0; k < ses.size(); k++) {
+                   handleScheduleEdge(ses.elementAt(k), false);
+               }
+               ses = null;
+           }
+           keys = null;
+           fe2ses.clear();
+           sn2fes.clear();
+       }
+    }
+    
+    private void handleScheduleEdge(ScheduleEdge se, boolean merge) {
+       int rate = 0;
+       int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
+       if(merge) {
+           try {
+               rate = (int)Math.ceil((se.getTransTime() - calInExeTime(se.getSourceFState()))/ se.getListExeTime());
+               if(rate < 0 ) {
+                   rate = 0;
+               }
+           } catch (Exception e) {
+               e.printStackTrace();
+           }
+           if(0 == rate) {
+               // clone the whole ScheduleNode lists starting with se's target
+               for(int j = 1; j < repeat; j++ ) {
+                   cloneSNodeList(se, true);
+               }
+               se.setNewRate(1);
+               se.setProbability(100);
            } else {
-               if(se.getNewRate() > 1){
+               repeat -= rate;
+               if(repeat > 0){
                    // clone the whole ScheduleNode lists starting with se's target
-                   for(int j = 1; j < se.getNewRate(); j++ ) {
+                   for(int j = 0; j < repeat; j++ ) {
                        cloneSNodeList(se, true);
                    }
-                   se.setNewRate(1);
-               } else if (se.getNewRate() == 1) {
-                   //merge the target ScheduleNode to the source ScheduleNode
-                   ((ScheduleNode)se.getSource()).merge(se);
-                   scheduleNodes.remove(se.getTarget());
-                   scheduleEdges.removeElement(se);
-                   se.setTarget((ScheduleNode)se.getSource());
-               }
+                   se.setNewRate(rate);
+                   se.setProbability(100);
+               }
            }
-       }
+           // merge the original ScheduleNode to the source ScheduleNode
+           ((ScheduleNode)se.getSource()).mergeSEdge(se);
+           scheduleNodes.remove(se.getTarget());
+           scheduleEdges.removeElement(se);
+           // As se has been changed into an internal edge inside a ScheduleNode, 
+           // change the source and target of se from original ScheduleNodes into ClassNodes.
+           se.setTarget(se.getTargetCNode());
+           se.setSource(se.getSourceCNode());
+       } else {
+           // clone the whole ScheduleNode lists starting with se's target
+           for(int j = 1; j < repeat; j++ ) {
+               cloneSNodeList(se, true);
+           }
+           se.setNewRate(1);
+           se.setProbability(100);
+       }
     }
     
     private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) {
        Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>();
        ScheduleNode csNode = (ScheduleNode)((ScheduleNode)sEdge.getTarget()).clone(cn2cn);
        scheduleNodes.add(csNode);
-               
+       
        // Clone all the external in ScheduleEdges
        int i;  
        if(copyIE) {
            Vector inedges = sEdge.getTarget().getInedgeVector();
            for(i = 0; i < inedges.size(); i++) {
                ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i);
-               ScheduleEdge se = new ScheduleEdge(csNode, "new", tse.getTask(), tse.getClassDescriptor());
-               se.setProbability(tse.getProbability());
-               se.setNewRate(1);
-               se.setFEdge(tse.getFEdge());
+               ScheduleEdge se = new ScheduleEdge(csNode, "new", tse.getClassDescriptor(), tse.getIsNew());
+               if(tse.getIsNew()) {
+                   //se.setProbability(tse.getProbability());
+                   se.setProbability(100);
+                   se.setNewRate(1);
+                   se.setFEdge(tse.getFEdge());
+               }
                se.setSourceCNode(tse.getSourceCNode());
                se.setTargetCNode(cn2cn.get(tse.getTargetCNode()));
                tse.getSource().addEdge(se);
@@ -212,6 +405,7 @@ public class ScheduleAnalysis {
            sEdge.setTarget(csNode);
            csNode.getInedgeVector().add(sEdge);
            sEdge.setTargetCNode(cn2cn.get(sEdge.getTargetCNode()));
+           sEdge.setTargetFState(null);
        }
        
        Queue<ScheduleNode> toClone = new LinkedList<ScheduleNode>();
@@ -234,9 +428,14 @@ public class ScheduleAnalysis {
                clone.add(tSNode);
                toClone.add((ScheduleNode)tse.getTarget());
                qcn2cn.add(tocn2cn);
-               ScheduleEdge se = new ScheduleEdge(tSNode, "new", tse.getTask(), tse.getClassDescriptor());
-               se.setProbability(tse.getProbability());
-               se.setNewRate(tse.getNewRate());
+               ScheduleEdge se = null;
+               if(tse.getIsNew()) {
+                   se = new ScheduleEdge(tSNode, "new", tse.getClassDescriptor(), tse.getIsNew());
+                   se.setProbability(tse.getProbability());
+                   se.setNewRate(tse.getNewRate());
+               } else {
+                   se = new ScheduleEdge(tSNode, "transmit", tse.getClassDescriptor(), false);
+               }
                se.setSourceCNode(cn2cn.get(tse.getSourceCNode()));
                se.setTargetCNode(tocn2cn.get(tse.getTargetCNode()));
                csNode.addEdge(se);
@@ -245,6 +444,131 @@ public class ScheduleAnalysis {
        }
     }
     
+    private int calInExeTime(FlagState fs) throws Exception {
+       int exeTime = 0;
+       ClassDescriptor cd = fs.getClassDescriptor();
+       ClassNode cNode = cd2ClassNode.get(cd);
+       exeTime = cNode.getFlagStates().elementAt(0).getExeTime() - fs.getExeTime();
+       while(true) {
+           Vector inedges = cNode.getInedgeVector();
+           if(inedges.size() > 1) {
+               throw new Exception("Error: ClassNode's inedges more than one!");
+           }
+           if(inedges.size() > 0) {
+               ScheduleEdge sEdge = (ScheduleEdge)inedges.elementAt(0);
+               cNode = (ClassNode)sEdge.getSource();
+               exeTime += cNode.getFlagStates().elementAt(0).getExeTime();
+           }else {
+               break;
+           }
+       }
+       exeTime = cNode.getScheduleNode().getExeTime() - exeTime;
+       return exeTime;
+    }
+    
+    private ScheduleNode splitSNode(ScheduleEdge se, boolean copy) {
+       FEdge fe = se.getFEdge();
+       FlagState fs = (FlagState)fe.getTarget();
+       FlagState nfs = (FlagState)fs.clone();
+       fs.getEdgeVector().removeAllElements();
+       nfs.getInedgeVector().removeAllElements();
+       ClassNode sCNode = se.getSourceCNode();
+       
+       // split the subtree whose root is nfs from the whole flag transition tree
+       Vector<FlagState> sfss = sCNode.getFlagStates();
+       Vector<FlagState> fStates = new Vector<FlagState>();
+       Queue<FlagState> toiterate = new LinkedList<FlagState>();
+       toiterate.add(nfs);
+       fStates.add(nfs);
+       while(!toiterate.isEmpty()){
+           FlagState tfs = toiterate.poll();
+           Iterator it_edges = tfs.edges();
+           while(it_edges.hasNext()) {
+               FlagState temp = (FlagState)((FEdge)it_edges.next()).getTarget();
+               if(!fStates.contains(temp)) {
+                   fStates.add(temp);
+                   toiterate.add(temp);
+                   sfss.removeElement(temp);
+               }
+           }
+       }
+       Vector<FlagState> sFStates = FlagState.DFS.topology(fStates, null);
+       // create a ClassNode and ScheduleNode for this subtree
+       ClassNode cNode = new ClassNode(sCNode.getClassDescriptor(), sFStates);
+       ScheduleNode sNode = new ScheduleNode(cNode);
+       cNode.setScheduleNode(sNode);
+       cNode.setSorted(true);
+       cNode.setTransTime(sCNode.getTransTime());
+       classNodes.add(cNode);
+       scheduleNodes.add(sNode);
+       try {
+           sNode.calExeTime();
+       } catch (Exception e) {
+           e.printStackTrace();
+       }
+       // flush the exeTime of fs and its ancestors
+       fs.setExeTime(0);
+       toiterate.add(fs);
+       while(!toiterate.isEmpty()) {
+           FlagState tfs = toiterate.poll();
+           int ttime = tfs.getExeTime();
+           Iterator it_inedges = tfs.inedges();
+           while(it_inedges.hasNext()) {
+               FEdge fEdge = (FEdge)it_inedges.next();
+               FlagState temp = (FlagState)fEdge.getSource();
+               int time = fEdge.getExeTime() + ttime;
+               if(temp.getExeTime() > time) {
+                   temp.setExeTime(time);
+                   toiterate.add(temp);
+               }
+           }
+       }
+       
+       
+       // create a 'trans' ScheudleEdge between this new ScheduleNode and se's source ScheduleNode
+       ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false);
+       sEdge.setTargetFState(fs);
+       sEdge.setFEdge(fe);
+       sEdge.setSourceCNode(sCNode);
+       sEdge.setTargetCNode(cNode);
+       sEdge.setTargetFState(nfs);
+       // todo
+       // Add calculation codes for calculating transmit time of an object 
+       sEdge.setTransTime(cNode.getTransTime());
+       se.getSource().addEdge(sEdge);
+       scheduleEdges.add(sEdge);
+       // redirect ScheudleEdges out of this subtree to the new ScheduleNode
+       Iterator it_sEdges = se.getSource().edges();
+       Vector<ScheduleEdge> toremove = new Vector<ScheduleEdge>();
+       while(it_sEdges.hasNext()) {
+           ScheduleEdge tse = (ScheduleEdge)it_sEdges.next();
+           if((tse != se) && (tse != sEdge) && (tse.getSourceCNode() == sCNode)) {
+               if((tse.getSourceFState() != fs) && (sFStates.contains(tse.getSourceFState()))) {
+                   tse.setSource(sNode);
+                   tse.setSourceCNode(cNode);
+                   sNode.getEdgeVector().addElement(tse);
+                   toremove.add(tse);
+               }
+           }
+       }
+       se.getSource().getEdgeVector().removeAll(toremove);
+       
+       if(!copy) {
+           //merge se into its source ScheduleNode
+           ((ScheduleNode)se.getSource()).mergeSEdge(se);
+           scheduleNodes.remove(se.getTarget());
+           scheduleEdges.removeElement(se);
+           // As se has been changed into an internal edge inside a ScheduleNode, 
+           // change the source and target of se from original ScheduleNodes into ClassNodes.
+           se.setTarget(se.getTargetCNode());
+           se.setSource(se.getSourceCNode());
+       } else {
+           handleScheduleEdge(se, true);
+       }
+       
+       return sNode;
+    }
+    
     public void schedule() {
        // Assign a core to each ScheduleNode
        int i = 0;
@@ -287,14 +611,7 @@ public class ScheduleAnalysis {
             output.println("\tsubgraph " + gn.getLabel() + "{");
             output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
             Iterator it_cnodes = gn.getClassNodesIterator();
-            if(gn.isclone()) {
-               while (it_cnodes.hasNext()) {
-                   ClassNode cn = (ClassNode) it_cnodes.next();
-                   output.println("\t\t" + cn.getLabel() + " [style=dashed, label=\"" + cn.getTextLabel() + "\", shape=box];");
-                }
-            } else {
-               traverseCNodes(output, it_cnodes);
-            }
+            traverseCNodes(output, it_cnodes);
             //Draw the internal 'new' edges
             Iterator it_edges =gn.getScheduleEdgesIterator();
             while(it_edges.hasNext()) {
@@ -322,16 +639,16 @@ public class ScheduleAnalysis {
             while(edges.hasNext()) {
                ScheduleEdge se = (ScheduleEdge)edges.next();
                output.print("\t");
-               if(((ScheduleNode)se.getSource()).isclone()) {
+               if(se.getSourceFState() == null) {
                    output.print(se.getSourceCNode().getLabel());
                } else {
                    output.print(se.getSourceFState().getLabel());
                }
                output.print(" -> ");
-               if(((ScheduleNode)se.getTarget()).isclone()) {
-                   output.println(se.getTargetCNode().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
+               if(se.getTargetFState() == null) {
+                   output.println(se.getTargetCNode().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed]");
                } else {
-                   output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed, ltail=" + gn.getLabel() + "];");
+                   output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed]");
                }
             }
         }
@@ -341,11 +658,15 @@ public class ScheduleAnalysis {
        //Draw clusters representing ClassNodes
         while (it.hasNext()) {
            ClassNode gn = (ClassNode) it.next();
-            output.println("\tsubgraph " + gn.getClusterLabel() + "{");
-            output.println("\t\tstyle=dashed;");
-            output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
-            traverseFlagStates(output, gn.getFlagStates());
-            output.println("\t}\n");
+           if(gn.isclone()) {
+               output.println("\t\t" + gn.getLabel() + " [style=dashed, label=\"" + gn.getTextLabel() + "\", shape=box];");
+           } else {
+               output.println("\tsubgraph " + gn.getClusterLabel() + "{");
+               output.println("\t\tstyle=dashed;");
+               output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
+               traverseFlagStates(output, gn.getFlagStates());
+               output.println("\t}\n");
+           }
         }
     }
     
@@ -367,7 +688,7 @@ public class ScheduleAnalysis {
                Namer name=(Namer) namers.get(i);
                String newlabel=name.nodeLabel(gn);
                String newparams=name.nodeOption(gn);
-
+               
                if (!newlabel.equals("") && !label.equals("")) {
                    label+=", ";
                }
@@ -376,6 +697,7 @@ public class ScheduleAnalysis {
                }
                label+=name.nodeLabel(gn);
            }
+           label += ":[" + ((FlagState)gn).getExeTime() + "]";
            
            if (!gn.merge)
                output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];");
@@ -400,7 +722,17 @@ public class ScheduleAnalysis {
                                if (!newoption.equals(""))
                                    edgedotnodeparams+=", "+newoption;
                            }
-                           
+                           edgelabel+=":[" + ((FEdge)edge).getExeTime() + "]";
+                           Hashtable<ClassDescriptor, NewObjInfo> hashtable = ((FEdge)edge).getNewObjInfoHashtable();
+                           if(hashtable != null) {
+                               Set<ClassDescriptor> keys = hashtable.keySet();
+                               Iterator it_keys = keys.iterator();
+                               while(it_keys.hasNext()) {
+                                   ClassDescriptor cd = (ClassDescriptor)it_keys.next();
+                                   NewObjInfo noi = hashtable.get(cd);
+                                   edgelabel += ":{ class " + cd.getSymbol() + " | " + noi.getNewRate() + " | (" + noi.getProbability() + "%) }";
+                               }
+                           }
                            output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];");
                        }
                     }
index 9d0a21e0ed4cca5e0b911ab5aa0a130a058c58d3..82479aa8c3a5143382cc7ddf9f1911281b6bb03f 100644 (file)
@@ -1,61 +1,87 @@
 package Analysis.Scheduling;
+import java.util.Iterator;
+
 import IR.*;
 import Analysis.TaskStateAnalysis.*;
 import Util.Edge;
+import Util.GraphNode;
 
 /* Edge *****************/
 
 public class ScheduleEdge extends Edge {
 
     private String label;
-    private final TaskDescriptor td;
     private final ClassDescriptor cd;
-    private FEdge fedge;
+    private boolean isNew = true;
+    
     private FlagState targetFState;
     private ClassNode sourceCNode;
     private ClassNode targetCNode;
-    private int newRate;
+    
     private int probability;
-    //private int parameterindex;
+    private int transTime;
+    private int listExeTime;
+    
+    private FEdge fedge;
+    private int newRate;
     
     /** Class Constructor
      * 
      */
-    public ScheduleEdge(ScheduleNode target, String label, TaskDescriptor td, ClassDescriptor cd/*, int parameterindex*/) {
+    public ScheduleEdge(ScheduleNode target, String label, ClassDescriptor cd) {
+       super(target);
+       this.fedge = null;
+       this.targetFState = null;
+       this.sourceCNode = null;
+       this.targetCNode = null;
+       this.label = label;
+       this.cd = cd;
+       this.newRate = -1;
+       this.probability = 100;
+       this.transTime = -1;
+       this.listExeTime = -1;
+    }
+    
+    public ScheduleEdge(ScheduleNode target, String label, ClassDescriptor cd, boolean isNew) {
        super(target);
        this.fedge = null;
        this.targetFState = null;
        this.sourceCNode = null;
        this.targetCNode = null;
        this.label = label;
-       this.td = td;
        this.cd = cd;
-       this.newRate = 1;
+       this.newRate = -1;
        this.probability = 100;
-       //this.parameterindex = parameterindex;
+       this.transTime = -1;
+       this.listExeTime = -1;
+       this.isNew = isNew;
     }
     
-    public void setTarget(ScheduleNode sn) {
+    public void setTarget(GraphNode sn) {
        this.target = sn;
     }
     
     public String getLabel() {
-       String completeLabel = label + ":" + Integer.toString(this.newRate) + ":(" + Integer.toString(this.probability) + ")";
+       String completeLabel = label;
+       if(isNew) {
+           completeLabel += ":" + Integer.toString(this.newRate);
+       }
+       completeLabel += ":(" + Integer.toString(this.probability) + "%)" + ":[" + Integer.toString(this.transTime) + "]";
        return completeLabel;
     }
     
     public int hashCode(){
        return target.hashCode()^label.hashCode();
     }
-
-    public TaskDescriptor getTask() {
-       return td;
-    }
     
     public ClassDescriptor getClassDescriptor() {
        return cd;
     }
     
+    public boolean getIsNew() {
+       return this.isNew;
+    }
+    
     public FEdge getFEdge() {
        return this.fedge;
     }
@@ -101,27 +127,31 @@ public class ScheduleEdge extends Edge {
     
     public void setTargetCNode(ClassNode targetCNode) {
        this.targetCNode = targetCNode;
+       this.transTime = targetCNode.getTransTime();
     }
-
-   /* public int getIndex() {
-       return parameterindex;
-    }*/
        
     public boolean equals(Object o) {
         if (o instanceof ScheduleEdge) {
            ScheduleEdge e=(ScheduleEdge)o;
            if ((e.label.equals(label))&&
                (e.target.equals(target))&&
-               (e.td.equals(td)) && 
+               (e.source.equals(source)) &&
                (e.cd.equals(cd)) && 
-               (e.fedge.equals(fedge)) && 
-               (e.targetFState.equals(targetFState)) && 
+               (e.fedge.equals(fedge)) &&  
                (e.sourceCNode.equals(sourceCNode)) &&
                (e.targetCNode.equals(targetCNode)) &&
                (e.newRate == newRate) && 
-               (e.probability == probability)/*&&
-               e.getIndex()==parameterindex*/)
-               return true;
+               (e.probability == probability) && 
+               (e.isNew == isNew) && 
+               (e.transTime == transTime) && 
+               (e.listExeTime == listExeTime))
+               if(e.targetFState != null) {
+                   return e.targetFState.equals(targetFState);
+               } else if(this.targetFState == null) {
+                   return true;
+               } else {
+                   return false;
+               }
         }
         return false;
     }
@@ -133,4 +163,36 @@ public class ScheduleEdge extends Edge {
     public void setNewRate(int nr) {
        this.newRate = nr;
     }
+    
+    public int getTransTime() {
+       return this.transTime;
+    }
+    
+    public void setTransTime(int transTime) {
+       this.transTime = transTime;
+    }
+    
+    public int getListExeTime() {
+       if(listExeTime == -1) {
+           // calculate the lisExeTime
+           listExeTime = ((ScheduleNode)this.getTarget()).getExeTime() + this.getTransTime() * this.getNewRate();
+           Iterator it_edges = this.getTarget().edges();
+           int temp = 0;
+           if(it_edges.hasNext()) {
+                  temp = ((ScheduleEdge)it_edges.next()).getListExeTime();
+           }
+           while(it_edges.hasNext()) {
+               int tetime = ((ScheduleEdge)it_edges.next()).getListExeTime();
+               if(temp < tetime) {
+                   temp = tetime;
+               }
+           }
+           listExeTime += temp;
+       }
+       return this.listExeTime;
+    }
+    
+    public void resetListExeTime() {
+       this.listExeTime = -1;
+    }
 }
index 5ea3b61d9cdafb74ac5855b7b5893d54ad2cfc5f..44b345b6f0fba276722fe474ca8d52d7d4c17d4b 100644 (file)
@@ -13,15 +13,15 @@ public class ScheduleNode extends GraphNode implements Cloneable{
     private int uid;
     private static int nodeID=0;
 
+    private Vector<ClassNode> classNodes;
+    Vector<ScheduleEdge> scheduleEdges;
+    
+    private int executionTime;
+    
     private int coreNum;
     private Vector tasks;
     private Hashtable<ClassDescriptor, Vector<ScheduleNode>> targetSNodes; 
     private boolean sorted = false;
-    
-    private boolean clone = false;
-
-    private Vector<ClassNode> classNodes;
-    Vector<ScheduleEdge> scheduleEdges;
 
     /** Class constructor
      * @param cd ClassDescriptor
@@ -30,6 +30,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{
     public ScheduleNode() {
        this.uid=ScheduleNode.nodeID++;
        this.coreNum = -1;
+       this.executionTime = -1;
     }
     
     public ScheduleNode(ClassNode cn) {
@@ -39,6 +40,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        this.scheduleEdges = new Vector<ScheduleEdge>();
        this.classNodes.add(cn);
        this.addEdge(cn.getEdgeVector());
+       this.executionTime = -1;
     }
    
     public int getuid() {
@@ -101,10 +103,6 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        this.sorted = sorted;
     }
     
-    public boolean isclone() {
-       return clone;
-    }
-    
     public String toString() {
        String temp = new String("");
        for(int i = 0; i < classNodes.size(); i++) {
@@ -113,7 +111,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        temp += getTextLabel();
        return temp;
     }
-
+    
     public Vector getClassNodes() {
        if(classNodes == null) {
            classNodes = new Vector<ClassNode>();
@@ -144,6 +142,28 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        scheduleEdges = null;
     }
     
+    public int getExeTime() {
+       if(this.executionTime == -1) {
+           try {
+               calExeTime();
+           } catch (Exception e) {
+               e.printStackTrace();
+           }
+       }
+       return this.executionTime;
+    }
+    
+    public void calExeTime() throws Exception {
+       if(this.classNodes.size() != 1) {
+           throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
+       }
+       ClassNode cn = this.classNodes.elementAt(0);
+       if(!cn.isSorted()) {
+           throw new Error("Error: Non-sorted ClassNode!");
+       }
+       this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
+    }
+    
     /** Tests for equality of two flagstate objects.
     */
     
@@ -152,7 +172,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{
            ScheduleNode fs=(ScheduleNode)o;
             if ((fs.getCoreNum() != this.coreNum) ||
                (fs.sorted != this.sorted) ||
-               (fs.clone != this.clone)){ 
+               (fs.executionTime != this.executionTime)){ 
                 return false;
             }
             if(fs.tasks != null) {
@@ -221,9 +241,17 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        }
        for(i = 0; i < this.scheduleEdges.size(); i++) {
            ScheduleEdge temp = this.scheduleEdges.elementAt(i);
-           ScheduleEdge se = new ScheduleEdge(o, "new", temp.getTask(), temp.getClassDescriptor());
+           ScheduleEdge se = null;
+           if(!temp.getIsNew()) {
+               se = new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false);
+           } else {
+               se = new ScheduleEdge(o, "new",temp.getClassDescriptor());
+           }
            se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
            se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
+           se.setProbability(temp.getProbability());
+           se.setNewRate(temp.getNewRate());
+           se.setTransTime(temp.getTransTime());
            tses.add(se);
        }
        o.classNodes = tcns;
@@ -232,12 +260,13 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        tses = null;
        o.inedges = new Vector();
        o.edges = new Vector();
-       
-       o.clone = true;
+
        return o;
     }
     
-    public void merge(ScheduleEdge se) {
+    public void mergeSEdge(ScheduleEdge se) {
+       assert(se.getIsNew());
+       
        Vector<ClassNode> targetCNodes = (Vector<ClassNode>)((ScheduleNode)se.getTarget()).getClassNodes();
        Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)((ScheduleNode)se.getTarget()).getScheduleEdges();
        
@@ -260,14 +289,60 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        targetSEdges = null;
        
        scheduleEdges.add(se);
+       se.resetListExeTime();
        se.getTarget().removeInedge(se);
        this.removeEdge(se);
-       //this.addEdge(se.getTarget().getEdgeVector());
        Iterator it_edges = se.getTarget().edges();
        while(it_edges.hasNext()) {
            ScheduleEdge tse = (ScheduleEdge)it_edges.next();
            tse.setSource(this);
            this.edges.addElement(tse);
+       }
+       
+       // As all tasks inside one ScheduleNode are executed sequentially,
+       // simply add the execution time of all the ClassNodes inside one ScheduleNode. 
+       if(this.executionTime == -1) {
+           this.executionTime = 0;
+       }
+       this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
+    }
+    
+    public void mergeSNode(ScheduleNode sn) throws Exception {
+       Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
+       Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
+       
+       for(int i = 0; i <  targetCNodes.size(); i++) {
+           targetCNodes.elementAt(i).setScheduleNode(this);
+       }
+       
+       if(classNodes == null) {
+           classNodes = targetCNodes;
+           scheduleEdges = targetSEdges;
+       } else {
+           if(targetCNodes.size() != 0) {
+               classNodes.addAll(targetCNodes);
+           }
+           if(targetSEdges.size() != 0) {
+               scheduleEdges.addAll(targetSEdges);
+           }
+       }
+       targetCNodes = null;
+       targetSEdges = null;
+
+       Iterator it_edges = sn.edges();
+       while(it_edges.hasNext()) {
+           ScheduleEdge tse = (ScheduleEdge)it_edges.next();
+           tse.setSource(this);
+           this.edges.addElement(tse);
+       }
+       
+       // As all tasks inside one ScheduleNode are executed sequentially,
+       // simply add the execution time of all the ClassNodes inside one ScheduleNode. 
+       if(this.executionTime == -1) {
+           throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
+       }
+       if(this.executionTime < sn.getExeTime()) {
+           this.executionTime = sn.getExeTime();
        }
     }
 }
index 19b4e5dfdac15226b4062727daa3885ecf0dada2..494748d1a04a4409d664e6821c6a8765fa7efb71 100644 (file)
@@ -13,6 +13,53 @@ public class FEdge extends Edge {
     private String label;
     private TaskDescriptor td;
     private int parameterindex;
+    
+    // jzhou
+    private int executeTime;
+    private Hashtable<ClassDescriptor, NewObjInfo> newObjInfos;
+    
+    public class NewObjInfo {
+       int newRate;
+       int probability;
+       
+       public NewObjInfo() {
+           newRate = 0;
+           probability = 0;
+       }
+       
+       public NewObjInfo(int newRate, int probability) {
+           this.newRate = newRate;
+           this.probability = probability;
+       }
+       
+       public int getNewRate() {
+           return this.newRate;
+       }
+       
+       public void setNewRate(int newRate) {
+           this.newRate = newRate;
+       }
+       
+       public int getProbability() {
+           return this.probability;
+       }
+       
+       public void setProbability(int probability) {
+           this.probability = probability;
+       }
+       
+       public boolean equals(Object o) {
+            if (o instanceof NewObjInfo) {
+               NewObjInfo e=(NewObjInfo)o;
+               if (e.newRate == this.newRate &&
+                   e.probability == this.probability) {
+                   return true;
+               }
+            }
+            return false;
+        }
+    }
+    
     /** Class Constructor
      * 
      */
@@ -21,6 +68,8 @@ public class FEdge extends Edge {
        this.label = label;
        this.td=td;
        this.parameterindex=parameterindex;
+       this.executeTime = -1;
+       this.newObjInfos = null;
     }
     
     public String getLabel() {
@@ -44,10 +93,45 @@ public class FEdge extends Edge {
             FEdge e=(FEdge)o;
            if (e.label.equals(label)&&
                e.target.equals(target)&&
+               e.source.equals(source) &&
                e.td==td&&
-               e.parameterindex==parameterindex)
-               return true;
+               e.parameterindex==parameterindex &&
+               e.executeTime == executeTime) {
+               if(this.newObjInfos != null) {
+                   if(e.newObjInfos == null) {
+                       return false;
+                   } else if(e.newObjInfos.equals(this.newObjInfos)) {
+                       return true;
+                   }
+               }
+           }
         }
         return false;
     }
+    
+    public int getExeTime() {
+       return this.executeTime;
+    }
+    
+    public void setExeTime(int eTime) {
+       this.executeTime = eTime;
+    }
+    
+    public Hashtable<ClassDescriptor, NewObjInfo> getNewObjInfoHashtable() {
+       return this.newObjInfos;
+    }
+    
+    public NewObjInfo getNewObjInfo(ClassDescriptor cd) {
+       if(this.newObjInfos == null) {
+           return null;
+       }
+       return this.newObjInfos.get(cd);
+    }
+    
+    public void addNewObjInfo(ClassDescriptor cd, int newRate, int probability) {
+       if(this.newObjInfos == null) {
+           this.newObjInfos = new Hashtable<ClassDescriptor, NewObjInfo>();
+       }
+       this.newObjInfos.put(cd, new NewObjInfo(newRate, probability));
+    }
 }
index b70ce0155cd14487fe53b41439b31ea73dbc2e50..730bb740a9c8107f2110e58c70b89b997115b16c 100644 (file)
@@ -1,4 +1,5 @@
 package Analysis.TaskStateAnalysis;
+import Analysis.Scheduling.ClassNode;
 import Analysis.TaskStateAnalysis.*;
 import IR.*;
 import IR.Tree.*;
@@ -10,7 +11,7 @@ import Util.GraphNode;
 /** This class is used to hold the flag states that a class in the Bristlecone 
  *  program can exist in, during runtime.
  */
-public class FlagState extends GraphNode {
+public class FlagState extends GraphNode implements Cloneable {
     public static final int ONETAG=1;
     public static final int NOTAGS=0;
     public static final int MULTITAGS=-1;
@@ -24,6 +25,9 @@ public class FlagState extends GraphNode {
     private boolean issourcenode;
     private Vector tasks;
     public static final int KLIMIT=2;
+    
+    // jzhou
+    private int executeTime;
 
     /** Class constructor
      *  Creates a new flagstate with all flags set to false.
@@ -35,6 +39,7 @@ public class FlagState extends GraphNode {
        this.tags=new Hashtable<TagDescriptor,Integer>();
        this.uid=FlagState.nodeid++;
        this.issourcenode=false;
+       this.executeTime = -1;
     }
 
     /** Class constructor
@@ -49,7 +54,7 @@ public class FlagState extends GraphNode {
        this.tags=tags;
        this.uid=FlagState.nodeid++;
        this.issourcenode=false;
-       
+       this.executeTime = -1;
     }
    
     public int getuid() {
@@ -69,9 +74,9 @@ public class FlagState extends GraphNode {
      */
       
     public boolean isSourceNode(){
-           return issourcenode;
-       }
-       
+       return issourcenode;
+    }
+    
     /**  Sets the flagstate as a source node. 
      */
     public void setAsSourceNode(){
@@ -175,7 +180,7 @@ public class FlagState extends GraphNode {
                //2 case
                HashSet newset1=(HashSet)flagstate.clone();
                Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
-
+               
                //1 case
                HashSet newset2=(HashSet)flagstate.clone();
                Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
@@ -195,20 +200,20 @@ public class FlagState extends GraphNode {
      *  @param flags an array of flagdescriptors.
      *  @return string representation of the flagstate.
      */
-       public String toString(FlagDescriptor[] flags)
-       {
-               StringBuffer sb = new StringBuffer(flagstate.size());
-               for(int i=0;i < flags.length; i++)
-               {
-                       if (get(flags[i]))
-                               sb.append(1);
-                       else
-                               sb.append(0);
-               }
-                       
-               return new String(sb);
-       }
-
+    public String toString(FlagDescriptor[] flags)
+    {
+       StringBuffer sb = new StringBuffer(flagstate.size());
+       for(int i=0;i < flags.length; i++)
+           {
+               if (get(flags[i]))
+                   sb.append(1);
+               else
+                   sb.append(0);
+           }
+       
+       return new String(sb);
+    }
+    
        /** Accessor method
         *  @return returns the classdescriptor of the flagstate.
         */
@@ -266,23 +271,23 @@ public class FlagState extends GraphNode {
                label+=", "+fd.toString();
        }
        for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
-               TagDescriptor td=(TagDescriptor)en_tags.nextElement();
-               switch (tags.get(td).intValue()){
-               case ONETAG:
-                   if (label==null)
-                       label=td.toString()+"(1)";
-                   else
-                       label+=", "+td.toString()+"(1)";
-                   break;
-               case MULTITAGS:
-                   if (label==null)
-                       label=td.toString()+"(n)";
-                   else
-                       label+=", "+td.toString()+"(n)";
-                   break;
-               default:
-                   break;
-               }
+           TagDescriptor td=(TagDescriptor)en_tags.nextElement();
+           switch (tags.get(td).intValue()){
+           case ONETAG:
+               if (label==null)
+                   label=td.toString()+"(1)";
+               else
+                   label+=", "+td.toString()+"(1)";
+               break;
+           case MULTITAGS:
+               if (label==null)
+                   label=td.toString()+"(n)";
+               else
+                   label+=", "+td.toString()+"(n)";
+               break;
+           default:
+               break;
+           }
        }
        if (label==null)
            return " ";
@@ -290,6 +295,61 @@ public class FlagState extends GraphNode {
     }
     
     public Enumeration getTags(){
-           return tags.keys();
+       return tags.keys();
+    }
+    
+    public int getExeTime() {
+       try {
+           if(this.executeTime == -1) {
+               calExeTime();
+           }
+       } catch (Exception e) {
+           e.printStackTrace();
+           System.exit(0);
+       }
+       return this.executeTime;
+    }
+    
+    public void setExeTime(int exeTime) {
+       this.executeTime = exeTime;
+    }
+    
+    public void calExeTime() throws Exception {
+       Iterator it = this.edges();
+       if(it.hasNext()) {
+           FEdge fe = (FEdge)it.next();
+           if(fe.getExeTime() == -1) {
+               throw new Exception("Error: Uninitiate FEdge!");
+           }
+           this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
+       } else {
+           this.executeTime = 0;
+       }
+       while(it.hasNext()) {
+           FEdge fe = (FEdge)it.next();
+           int temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
+           if(temp < this.executeTime) {
+               this.executeTime = temp;
+           }
+       }
+    }
+    
+    public Object clone() {
+       FlagState o = null;
+       try {
+           o = (FlagState)super.clone();
+       } catch(CloneNotSupportedException e){
+           e.printStackTrace();
+       }
+       o.uid = FlagState.nodeid++;
+       o.edges = new Vector();
+       for(int i = 0; i < this.edges.size(); i++) {
+           o.edges.addElement(this.edges.elementAt(i));
+       }
+       o.inedges = new Vector();
+       for(int i = 0; i < this.inedges.size(); i++) {
+           o.inedges.addElement(this.inedges.elementAt(i));
+       }
+       return o;
     }
 }