Add support for multi-parameter tasks as well as tag in multi-core version
authorjzhou <jzhou>
Wed, 14 May 2008 22:08:32 +0000 (22:08 +0000)
committerjzhou <jzhou>
Wed, 14 May 2008 22:08:32 +0000 (22:08 +0000)
Robust/src/Analysis/Scheduling/Schedule.java
Robust/src/Analysis/Scheduling/ScheduleAnalysis.java
Robust/src/Analysis/Scheduling/ScheduleEdge.java
Robust/src/Analysis/Scheduling/ScheduleNode.java
Robust/src/Analysis/TaskStateAnalysis/FlagState.java
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/Flat/BuildCodeMultiCore.java
Robust/src/IR/Flat/BuildFlat.java
Robust/src/Main/Main.java
Robust/src/Runtime/Queue.c
Robust/src/Runtime/multicoretask.c

index 3fedbb6c8e20d7530966c2dab080785125e2c4f8..246fb2ab64828a4f68f7de572dba3ab4edbadb78 100644 (file)
@@ -17,6 +17,8 @@ public class Schedule {
     private Hashtable<FlagState, FlagState> targetFState;
     private Vector<Integer> ancestorCores;
     private Vector<Integer> childCores;
+    private Hashtable<FlagState, Vector<Integer>> allyCores;
+    private Hashtable<TaskDescriptor, Vector<FlagState>> td2fs;
     
     public Schedule(int coreNum) {
        super();
@@ -25,6 +27,8 @@ public class Schedule {
        this.targetCores = null;
        this.targetFState = null;
        this.ancestorCores = null;
+       this.allyCores = null;
+       this.td2fs = null;
     }
 
     public int getCoreNum() {
@@ -52,6 +56,28 @@ public class Schedule {
        }
        return targetFState.get(fstate);
     }
+    
+    public Hashtable<FlagState, Vector<Integer>> getAllyCoreTable() {
+        return this.allyCores;
+    }
+    
+    public Vector<Integer> getAllyCores(FlagState fstate) {
+       if(this.allyCores == null) {
+           return null;
+       }
+       return this.allyCores.get(fstate);
+    }
+    
+    public Hashtable<TaskDescriptor, Vector<FlagState>> getTd2FsTable() {
+        return this.td2fs;
+    }
+    
+    public Vector<FlagState> getFStates4TD(TaskDescriptor td) {
+       if(this.td2fs == null) {
+           return null;
+       }
+       return this.td2fs.get(td);
+    }
 
     public void addTargetCore(FlagState fstate, Integer targetCore/*, Integer num*/) {
        if(this.targetCores == null) {
@@ -83,6 +109,31 @@ public class Schedule {
            this.targetFState.put(fstate, tfstate);
        //}
     }
+    
+    public void addAllyCore(FlagState fstate, Integer targetCore/*, Integer num*/) {
+       if(this.allyCores == null) {
+           this.allyCores = new Hashtable<FlagState, Vector<Integer>>();
+       }
+       if(!this.allyCores.containsKey(fstate)) {
+           this.allyCores.put(fstate, new Vector<Integer>());
+       }
+       if((this.coreNum != targetCore.intValue()) && (!this.allyCores.get(fstate).contains(targetCore))) {
+           this.allyCores.get(fstate).add(targetCore); // there may have some duplicate items,
+                                                         // which reflects probabilities.
+       }
+    }
+    
+    public void addFState4TD(TaskDescriptor td, FlagState fstate) {
+       if(this.td2fs == null) {
+           this.td2fs = new Hashtable<TaskDescriptor, Vector<FlagState>>();
+       }
+       if(!this.td2fs.containsKey(td)) {
+           this.td2fs.put(td, new Vector<FlagState>());
+       }
+       if(!this.td2fs.get(td).contains(fstate)) {
+           this.td2fs.get(td).add(fstate);
+       }
+    }
 
     public Vector<TaskDescriptor> getTasks() {
         return tasks;
index 937f7d4239e6ace5cc61c37ea88bee871aa53386..ac476561225262b150af6c9c3397628b3f2b1a16 100644 (file)
@@ -138,7 +138,7 @@ public class ScheduleAnalysis {
                                ClassDescriptor pcd = pfs.getClassDescriptor();
                                ClassNode pcNode = cdToCNodes.get(pcd);
                                
-                               ScheduleEdge sEdge = new ScheduleEdge(sNode, "new", root, 0);//new ScheduleEdge(sNode, "new", cd, 0);
+                               ScheduleEdge sEdge = new ScheduleEdge(sNode, "new", root, ScheduleEdge.NEWEDGE, 0);
                                sEdge.setFEdge(pfe);
                                sEdge.setSourceCNode(pcNode);
                                sEdge.setTargetCNode(cNode);
@@ -161,32 +161,77 @@ public class ScheduleAnalysis {
        }
        cdToCNodes = null;
        
-       // Do topology sort of the ClassNodes and ScheduleEdges.
-       Vector<ScheduleEdge> ssev = new Vector<ScheduleEdge>();
-       Vector<ScheduleNode> tempSNodes = ClassNode.DFS.topology(scheduleNodes, ssev);
-       scheduleNodes.removeAllElements();
-       scheduleNodes = tempSNodes;
-       tempSNodes = null;
-       scheduleEdges.removeAllElements();
-       scheduleEdges = ssev;
-       ssev = null;
-       sorted = true;
+       // Create 'associate' edges between the ScheduleNodes.
+       /*Iterator<TaskDescriptor> it_tasks = (Iterator<TaskDescriptor>)state.getTaskSymbolTable().getDescriptorsIterator();
+       while(it_tasks.hasNext()) {
+           TaskDescriptor td = it_tasks.next();
+           int numParams = td.numParameters();
+           if(!(numParams > 1)) {
+               // single parameter task
+               continue;
+           }
+           ClassNode[] cNodes = new ClassNode[numParams];
+           for(i = 0; i < numParams; ++i) {
+               cNodes[i] = this.cd2ClassNode.get(td.getParamType(i).getClassDesc());
+           }
+           Vector<FEdge> fev = (Vector<FEdge>)taskanalysis.getFEdgesFromTD(td);
+           // for each fedge associated to this td, create an associate ScheduleEdge
+           // from the ClassNode containg this FEdge to every other ClassNode representing
+           // other parameters.
+           for(i = 0; i < fev.size(); ++i) {
+               FEdge tmpfe = fev.elementAt(i);
+               for(int j = 0; j < numParams; ++j) {
+                   if(j == tmpfe.getIndex()) {
+                       continue;
+                   }
+                   FlagState fs = (FlagState)tmpfe.getSource();
+                   ScheduleEdge se = new ScheduleEdge(cNodes[j].getScheduleNode(), "associate", fs, ScheduleEdge.ASSOCEDGE, 0);
+                   se.setFEdge(tmpfe);
+                   se.setSourceCNode(cNodes[i]);
+                   se.setTargetCNode(cNodes[j]);
+                   // targetFState is always null
+                   cNodes[i].getScheduleNode().addAssociateSEdge(se);
+                   // scheduleEdges only holds new/transmit edges
+                   //scheduleEdges.add(se);  
+                   fs.addAlly(se);
+               }
+           } 
+       }*/
 
        // Break down the 'cycle's
-       for(i = 0; i < toBreakDown.size(); i++ ) {
-           cloneSNodeList(toBreakDown.elementAt(i), false);
-       }
-       toBreakDown = null;
+       try {
+           for(i = 0; i < toBreakDown.size(); i++ ) {
+               cloneSNodeList(toBreakDown.elementAt(i), false);
+           }
+           toBreakDown = null;
+       } catch (Exception e) {
+           e.printStackTrace();
+           System.exit(-1);
+       }
        
        // Remove fake 'new' edges
        for(i = 0; i < scheduleEdges.size(); i++) {
-           ScheduleEdge se = scheduleEdges.elementAt(i);
+           /*if(ScheduleEdge.NEWEDGE != scheduleEdges.elementAt(i).getType()) {
+               continue;
+           }*/
+           ScheduleEdge se = (ScheduleEdge)scheduleEdges.elementAt(i);
            if((0 == se.getNewRate()) || (0 == se.getProbability())) {
                scheduleEdges.removeElement(se);
                scheduleNodes.removeElement(se.getTarget());
            }
        }
        
+       // Do topology sort of the ClassNodes and ScheduleEdges.
+       Vector<ScheduleEdge> ssev = new Vector<ScheduleEdge>();
+       Vector<ScheduleNode> tempSNodes = ClassNode.DFS.topology(scheduleNodes, ssev);
+       scheduleNodes.removeAllElements();
+       scheduleNodes = tempSNodes;
+       tempSNodes = null;
+       scheduleEdges.removeAllElements();
+       scheduleEdges = ssev;
+       ssev = null;
+       sorted = true;
+       
        SchedulingUtil.printScheduleGraph("scheduling_ori.dot", this.scheduleNodes);
     }
     
@@ -198,39 +243,46 @@ public class ScheduleAnalysis {
        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(preSNode == null) {
-               preSNode = (ScheduleNode)se.getSource();
-           }
-           if(se.getIsNew()) {
+           ScheduleEdge se = (ScheduleEdge)scheduleEdges.elementAt(i-1);
+           if(ScheduleEdge.NEWEDGE == se.getType()) {
+               if(preSNode == null) {
+                   preSNode = (ScheduleNode)se.getSource();
+               }
+           
                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()));
+                       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);
+                           }
+                       }
                    } catch (Exception e) {
                        e.printStackTrace();
-                   }
-                   for(int j = rate - 1; j > 0; j--) {
-                       for(int k = repeat; k > 0; k--) {
-                           cloneSNodeList(se, true);
-                       }
+                       System.exit(-1);
                    }
                } 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) {
+                       // check the topology sort, only process those after se.getSource()
                        if(preSNode.getFinishingTime() < se.getSource().getFinishingTime()) {
                            if(sn2fes.containsKey(preSNode)) {
                                Vector<FEdge> fes = sn2fes.remove(preSNode);
@@ -263,7 +315,7 @@ public class ScheduleAnalysis {
                        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
+                   // if fe is the last task inside this ClassNode, delay the expanding and merging until we find all such 'new' edges
                    // associated with a last task inside this ClassNode
                    if(!fe.getTarget().edges().hasNext()) {
                        if(fe2ses.get(fe) == null) {
@@ -272,8 +324,12 @@ public class ScheduleAnalysis {
                        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);
+                       if(!fe2ses.get(fe).contains(se)) {
+                           fe2ses.get(fe).add(se);
+                       }
+                       if(!sn2fes.get((ScheduleNode)se.getSource()).contains(fe)) {
+                           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))) {
@@ -351,55 +407,61 @@ public class ScheduleAnalysis {
     }
     
     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;
+       try {
+           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();
                }
-           } catch (Exception e) {
-               e.printStackTrace();
-           }
-           if(0 == rate) {
+               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 {
+                   repeat -= rate;
+                   if(repeat > 0){
+                       // clone the whole ScheduleNode lists starting with se's target
+                       for(int j = 0; j < repeat; j++ ) {
+                           cloneSNodeList(se, true);
+                       }
+                       se.setNewRate(rate);
+                       se.setProbability(100);
+                   }
+               }
+               // merge the original ScheduleNode to the source ScheduleNode
+               ((ScheduleNode)se.getSource()).mergeSEdge(se);
+               scheduleNodes.remove(se.getTarget());
+               scheduleEdges.remove(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());
+               se.getTargetCNode().addEdge(se);
+           } 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);
-           } else {
-               repeat -= rate;
-               if(repeat > 0){
-                   // clone the whole ScheduleNode lists starting with se's target
-                   for(int j = 0; j < repeat; j++ ) {
-                       cloneSNodeList(se, true);
-                   }
-                   se.setNewRate(rate);
-                   se.setProbability(100);
-               }
-           }
-           // merge the original ScheduleNode to the source ScheduleNode
-           ((ScheduleNode)se.getSource()).mergeSEdge(se);
-           scheduleNodes.remove(se.getTarget());
-           scheduleEdges.remove(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);
+       } catch (Exception e) {
+           e.printStackTrace();
+           System.exit(-1);
        }
     }
     
-    private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) {
-       Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>();
+    private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) throws Exception {
+       Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>(); // hashtable from classnode in orignal se's targe to cloned one
        ScheduleNode csNode = (ScheduleNode)((ScheduleNode)sEdge.getTarget()).clone(cn2cn, 0);
        scheduleNodes.add(csNode);
        
@@ -410,12 +472,28 @@ public class ScheduleAnalysis {
            for(i = 0; i < inedges.size(); i++) {
                ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i);
                ScheduleEdge se;
-               if(tse.getIsNew()) {
-                   se = new ScheduleEdge(csNode, "new", tse.getFstate(), tse.getIsNew(), 0); //new ScheduleEdge(csNode, "new", tse.getClassDescriptor(), tse.getIsNew(), 0);
+               switch(tse.getType()) {
+               case ScheduleEdge.NEWEDGE: {
+                   se = new ScheduleEdge(csNode, "new", tse.getFstate(), tse.getType(), 0);
                    se.setProbability(100);
                    se.setNewRate(1);
-               } else {
-                   se = new ScheduleEdge(csNode, "transmit", tse.getFstate(), false, 0);//new ScheduleEdge(csNode, "transmit", tse.getClassDescriptor(), false, 0);
+                   break;
+               }
+               case ScheduleEdge.TRANSEDGE: {
+                   se = new ScheduleEdge(csNode, "transmit", tse.getFstate(), tse.getType(), 0);
+                   se.setProbability(tse.getProbability());
+                   se.setNewRate(tse.getNewRate());
+                   break;
+               }
+               /*case ScheduleEdge.ASSOCEDGE: {
+                   se = new ScheduleEdge(csNode, "associate", tse.getFstate(), tse.getType(), 0);
+                   se.setProbability(tse.getProbability());
+                   se.setNewRate(tse.getNewRate());
+                   break;
+               }*/
+               default: {
+                   throw new Exception("Error: not valid ScheduleEdge here");
+               }
                }
                se.setSourceCNode(tse.getSourceCNode());
                se.setTargetCNode(cn2cn.get(tse.getTargetCNode()));
@@ -426,6 +504,31 @@ public class ScheduleAnalysis {
                scheduleEdges.add(se);
            }
            inedges = null;
+           
+           // in associate ScheduleEdgs
+           /*inedges = ((ScheduleNode)sEdge.getTarget()).getInAssociateSEdges();
+           for(i = 0; i < inedges.size(); i++) {
+               ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i);
+               ScheduleEdge se;
+               switch(tse.getType()) {
+               case ScheduleEdge.ASSOCEDGE: {
+                   se = new ScheduleEdge(csNode, "associate", tse.getFstate(), tse.getType(), 0);
+                   se.setProbability(tse.getProbability());
+                   se.setNewRate(tse.getNewRate());
+                   break;
+               }
+               default: {
+                   throw new Exception("Error: not valid ScheduleEdge here");
+               }
+               }
+               se.setSourceCNode(tse.getSourceCNode());
+               se.setTargetCNode(cn2cn.get(tse.getTargetCNode()));
+               se.setFEdge(tse.getFEdge());
+               se.setTargetFState(tse.getTargetFState());
+               se.setIsclone(true);
+               ((ScheduleNode)tse.getSource()).addAssociateSEdge(se);
+           }
+           inedges = null;*/
        } else {
            sEdge.getTarget().removeInedge(sEdge);
            sEdge.setTarget(csNode);
@@ -435,11 +538,15 @@ public class ScheduleAnalysis {
            sEdge.setIsclone(true);
        }
        
-       Queue<ScheduleNode> toClone = new LinkedList<ScheduleNode>();
-       Queue<ScheduleNode> clone = new LinkedList<ScheduleNode>();
-       Queue<Hashtable> qcn2cn = new LinkedList<Hashtable>();
+       Queue<ScheduleNode> toClone = new LinkedList<ScheduleNode>(); // all nodes to be cloned
+       Queue<ScheduleNode> clone = new LinkedList<ScheduleNode>(); //clone nodes
+       Queue<Hashtable> qcn2cn = new LinkedList<Hashtable>(); // queue of the mappings of classnodes inside cloned ScheduleNode
+       Vector<ScheduleNode> origins = new Vector<ScheduleNode>(); // queue of source ScheduleNode cloned
+       Hashtable<ScheduleNode, ScheduleNode> sn2sn = new Hashtable<ScheduleNode, ScheduleNode>(); // mapping from cloned ScheduleNode to clone ScheduleNode
        clone.add(csNode);
        toClone.add((ScheduleNode)sEdge.getTarget());
+       origins.addElement((ScheduleNode)sEdge.getTarget());
+       sn2sn.put((ScheduleNode)sEdge.getTarget(), csNode);
        qcn2cn.add(cn2cn);
        while(!toClone.isEmpty()) {
            Hashtable<ClassNode, ClassNode> tocn2cn = new Hashtable<ClassNode, ClassNode>();
@@ -454,19 +561,33 @@ public class ScheduleAnalysis {
                scheduleNodes.add(tSNode);
                clone.add(tSNode);
                toClone.add((ScheduleNode)tse.getTarget());
+               origins.addElement((ScheduleNode)tse.getTarget());
+               sn2sn.put((ScheduleNode)tse.getTarget(), tSNode);
                qcn2cn.add(tocn2cn);
                ScheduleEdge se = null;
-               if(tse.getIsNew()) {
-                   se = new ScheduleEdge(tSNode, "new", tse.getFstate(), tse.getIsNew(), 0);//new ScheduleEdge(tSNode, "new", tse.getClassDescriptor(), tse.getIsNew(), 0);
-                   se.setProbability(tse.getProbability());
-                   se.setNewRate(tse.getNewRate());
-               } else {
-                   se = new ScheduleEdge(tSNode, "transmit", tse.getFstate(), false, 0);//new ScheduleEdge(tSNode, "transmit", tse.getClassDescriptor(), false, 0);
+               switch(tse.getType()) {
+               case ScheduleEdge.NEWEDGE: {
+                   se = new ScheduleEdge(tSNode, "new", tse.getFstate(), tse.getType(), 0);
+                   break;
+               }
+               case ScheduleEdge.TRANSEDGE: {
+                   se = new ScheduleEdge(tSNode, "transmit", tse.getFstate(), tse.getType(), 0);
+                   break;
+               }
+               /*case ScheduleEdge.ASSOCEDGE: {
+                   se = new ScheduleEdge(tSNode, "associate", tse.getFstate(), tse.getType(), 0);
+                   break;
+               }*/
+               default: {
+                   throw new Exception("Error: not valid ScheduleEdge here");
+               }
                }
                se.setSourceCNode(cn2cn.get(tse.getSourceCNode()));
                se.setTargetCNode(tocn2cn.get(tse.getTargetCNode()));
                se.setFEdge(tse.getFEdge());
                se.setTargetFState(tse.getTargetFState());
+               se.setProbability(tse.getProbability());
+               se.setNewRate(tse.getNewRate());
                se.setIsclone(true);
                csNode.addEdge(se);
                scheduleEdges.add(se);
@@ -474,6 +595,33 @@ public class ScheduleAnalysis {
            tocn2cn = null;
            edges = null;
        }
+
+       // associate ScheduleEdges
+       /*for(int j = 0; j < origins.size(); ++j) {
+           ScheduleNode osNode = origins.elementAt(i);
+           Vector<ScheduleEdge> edges = osNode.getAssociateSEdges();
+           ScheduleNode csNode = sn2sn.get(osNode);
+           for(i = 0; i < edges.size(); i++) {
+               ScheduleEdge tse = (ScheduleEdge)edges.elementAt(i);
+               assert(tse.getType() == ScheduleEdge.ASSOCEDGE);
+               ScheduleNode tSNode = (ScheduleNode)tse.getTarget();
+               if(origins.contains(tSNode)) {
+                   tSNode = sn2sn.get(tSNode);
+               }
+               ScheduleEdge se = new ScheduleEdge(tSNode, "associate", tse.getFstate(), tse.getType(), 0);
+               se.setSourceCNode(cn2cn.get(tse.getSourceCNode()));
+               se.setTargetCNode(tocn2cn.get(tse.getTargetCNode()));
+               se.setFEdge(tse.getFEdge());
+               se.setTargetFState(tse.getTargetFState());
+               se.setProbability(tse.getProbability());
+               se.setNewRate(tse.getNewRate());
+               se.setIsclone(true);
+               csNode.addAssociateSEdge(se);
+           }
+           tocn2cn = null;
+           edges = null;
+       }*/
+       
        toClone = null;
        clone = null;
        qcn2cn = null;
@@ -487,10 +635,18 @@ public class ScheduleAnalysis {
        exeTime = cNode.getFlagStates().elementAt(0).getExeTime() - fs.getExeTime();
        while(true) {
            Vector inedges = cNode.getInedgeVector();
+           // Now that there are associate ScheduleEdges, there may be multiple inedges of a ClassNode
            if(inedges.size() > 1) {
                throw new Exception("Error: ClassNode's inedges more than one!");
            }
            if(inedges.size() > 0) {
+               /*ScheduleEdge sEdge = null;
+               for(int i = 0; i < inedges.size(); ++i) {
+                   sEdge = (ScheduleEdge)inedges.elementAt(i);
+                   if(sEdge.getType() == ScheduleEdge.NEWEDGE) {
+                       break;
+                   }
+               }*/
                ScheduleEdge sEdge = (ScheduleEdge)inedges.elementAt(0);
                cNode = (ClassNode)sEdge.getSource();
                exeTime += cNode.getFlagStates().elementAt(0).getExeTime();
@@ -504,6 +660,8 @@ public class ScheduleAnalysis {
     }
     
     private ScheduleNode splitSNode(ScheduleEdge se, boolean copy) {
+       assert(ScheduleEdge.NEWEDGE == se.getType());
+       
        FEdge fe = se.getFEdge();
        FlagState fs = (FlagState)fe.getTarget();
        FlagState nfs = (FlagState)fs.clone();
@@ -565,12 +723,12 @@ public class ScheduleAnalysis {
        toiterate = null;
        
        // create a 'trans' ScheudleEdge between this new ScheduleNode and se's source ScheduleNode
-       ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", fs, false, 0);//new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false, 0);
+       ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", fs, ScheduleEdge.TRANSEDGE, 0);//new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false, 0);
        sEdge.setFEdge(fe);
        sEdge.setSourceCNode(sCNode);
        sEdge.setTargetCNode(cNode);
        sEdge.setTargetFState(nfs);
-       // todo
+       // TODO
        // Add calculation codes for calculating transmit time of an object 
        sEdge.setTransTime(cNode.getTransTime());
        se.getSource().addEdge(sEdge);
@@ -605,7 +763,6 @@ public class ScheduleAnalysis {
        toremove.clear();
        // 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)) {
@@ -621,17 +778,23 @@ public class ScheduleAnalysis {
        toremove = null;
        sFStates = null;
        
-       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);
+       try {
+           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());
+               se.getTargetCNode().addEdge(se);
+           } else {
+               handleScheduleEdge(se, true);
+           }
+       } catch (Exception e) {
+           e.printStackTrace();
+           System.exit(-1);
        }
        
        return sNode;
@@ -651,6 +814,9 @@ public class ScheduleAnalysis {
        // Enough cores, no need to merge more ScheduleEdge
        if(!(reduceNum > 0)) {
            this.scheduleGraphs.addElement(this.scheduleNodes);
+           int gid = 1;
+           String path = "scheduling_" + gid + ".dot";
+           SchedulingUtil.printScheduleGraph(path, this.scheduleNodes);
        } else {
            // sort the ScheduleEdges in dececending order of transmittime
            Vector<ScheduleEdge> sEdges = new Vector<ScheduleEdge>();
@@ -721,7 +887,17 @@ public class ScheduleAnalysis {
            this.schedulings = new Vector<Vector<Schedule>>();
        }
        
+       Vector<TaskDescriptor> multiparamtds = new Vector<TaskDescriptor>();
+       Iterator it_tasks = state.getTaskSymbolTable().getDescriptorsIterator();
+       while(it_tasks.hasNext()) {
+           TaskDescriptor td = (TaskDescriptor)it_tasks.next();
+           if(td.numParameters() > 1) {
+               multiparamtds.addElement(td);
+           }
+       }
+       
        for(int i = 0; i < this.scheduleGraphs.size(); i++) {
+           Hashtable<TaskDescriptor, Vector<Schedule>> td2cores = new Hashtable<TaskDescriptor, Vector<Schedule>>(); // multiparam tasks reside on which cores
            Vector<ScheduleNode> scheduleGraph = this.scheduleGraphs.elementAt(i);
            Vector<Schedule> scheduling = new Vector<Schedule>(scheduleGraph.size());
            // for each ScheduleNode create a schedule node representing a core
@@ -751,6 +927,16 @@ public class ScheduleAnalysis {
                        while(it_edges.hasNext()) {
                            TaskDescriptor td = ((FEdge)it_edges.next()).getTask();
                            tmpSchedule.addTask(td);
+                           if(td.numParameters() > 1) {
+                               if(!td2cores.containsKey(td)) {
+                                   td2cores.put(td, new Vector<Schedule>());
+                               }
+                               Vector<Schedule> tmpcores = td2cores.get(td);
+                               if(!tmpcores.contains(tmpSchedule)) {
+                                   tmpcores.add(tmpSchedule);
+                               }
+                               tmpSchedule.addFState4TD(td, fs);
+                           }
                            if(td.getParamType(0).getClassDesc().getSymbol().equals(TypeUtil.StartupClass)) {
                                assert(!setstartupcore);
                                startupcore = j;
@@ -773,13 +959,35 @@ public class ScheduleAnalysis {
                    ScheduleEdge se = (ScheduleEdge)it_edges.next();
                    ScheduleNode target = (ScheduleNode)se.getTarget();
                    Integer targetcore = sn2coreNum.get(target);
-                   if(se.getIsNew()) {
+                   switch(se.getType()) {
+                   case ScheduleEdge.NEWEDGE: {
                        for(int k = 0; k < se.getNewRate(); k++) {
                            tmpSchedule.addTargetCore(se.getFstate(), targetcore);
                        }
-                   } else {
+                       break;
+                   }
+                   case ScheduleEdge.TRANSEDGE: {
                        // 'transmit' edge
                        tmpSchedule.addTargetCore(se.getFstate(), targetcore, se.getTargetFState());
+                       // check if missed some FlagState associated with some multi-parameter 
+                       // task, which has been cloned when splitting a ClassNode
+                       FlagState fs = se.getSourceFState();
+                       FlagState tfs = se.getTargetFState();
+                       Iterator it = tfs.edges();
+                       while(it.hasNext()) {
+                           TaskDescriptor td = ((FEdge)it.next()).getTask();
+                           if(td.numParameters() > 1) {
+                               if(tmpSchedule.getTasks().contains(td)) {
+                                   tmpSchedule.addFState4TD(td, fs);
+                               }
+                           }
+                       }
+                       break;
+                   }
+                   /*case ScheduleEdge.ASSOCEDGE: {
+                       //TODO
+                       +
+                   }*/
                    }
                    tmpSchedule.addChildCores(targetcore);
                    if((targetcore.intValue() != j) && (!ancestorCores[targetcore.intValue()].contains((Integer.valueOf(j))))) {
@@ -789,22 +997,60 @@ public class ScheduleAnalysis {
                it_edges = sn.getScheduleEdgesIterator();
                while(it_edges.hasNext()) {
                    ScheduleEdge se = (ScheduleEdge)it_edges.next();
-                   if(se.getIsNew()) {
+                   switch(se.getType()) {
+                   case ScheduleEdge.NEWEDGE: {
                        for(int k = 0; k < se.getNewRate(); k++) {
                            tmpSchedule.addTargetCore(se.getFstate(), j);
                        }
-                   } else {
+                       break;
+                   }
+                   case ScheduleEdge.TRANSEDGE: {
                        // 'transmit' edge
                        tmpSchedule.addTargetCore(se.getFstate(), j, se.getTargetFState());
+                       break;
+                   }
+                   /*case ScheduleEdge.ASSOCEDGE: {
+                       //TODO
+                       +
+                   }*/
                    }
                }
                scheduling.add(tmpSchedule);
-           }
+           }       
+           
            leafcores.removeElement(Integer.valueOf(startupcore));
            ancestorCores[startupcore] = leafcores;
-           for(j = 0; j < this.coreNum; ++j) {
+           int number = this.coreNum;
+           if(scheduling.size() < number) {
+               number = scheduling.size();
+           }
+           for(j = 0; j < number; ++j) {
                scheduling.elementAt(j).setAncestorCores(ancestorCores[j]);
            }
+           
+           // set up all the associate ally cores
+           if(multiparamtds.size() > 0) {              
+               Object[] tds = (td2cores.keySet().toArray());
+               for(j = 0; j < tds.length; ++j) {
+                   TaskDescriptor td = (TaskDescriptor)tds[j];
+                   Vector<Schedule> cores = td2cores.get(td);
+                   if(cores.size() == 1) {
+                       continue;
+                   }
+                   for(int k = 0; k < cores.size(); ++k) {
+                       Schedule tmpSchedule = cores.elementAt(k);
+                       Vector<FlagState> tmpfss = tmpSchedule.getFStates4TD(td);
+                       for(int h = 0; h < tmpfss.size(); ++h) {
+                           for(int l = 0; l < cores.size(); ++l) {
+                               if(l != k) {
+                                   tmpSchedule.addAllyCore(tmpfss.elementAt(h), cores.elementAt(l).getCoreNum());
+                               }
+                           }
+                       }
+                   }
+               }
+           }
+           
            this.schedulings.add(scheduling);
        }
        
@@ -833,13 +1079,23 @@ public class ScheduleAnalysis {
            ScheduleNode ctarget = sn2sn.get(sse.getTarget());
            Hashtable<ClassNode, ClassNode> sourcecn2cn = sn2hash.get(csource);
            Hashtable<ClassNode, ClassNode> targetcn2cn = sn2hash.get(ctarget);
-           ScheduleEdge se;
-           if(sse.getIsNew()) {
-               se = new ScheduleEdge(ctarget, "new", sse.getFstate(), sse.getIsNew(), gid);//new ScheduleEdge(ctarget, "new", sse.getClassDescriptor(), sse.getIsNew(), gid);
+           ScheduleEdge se =  null;
+           switch(sse.getType()) {
+           case ScheduleEdge.NEWEDGE: {
+               se = new ScheduleEdge(ctarget, "new", sse.getFstate(), sse.getType(), gid);//new ScheduleEdge(ctarget, "new", sse.getClassDescriptor(), sse.getIsNew(), gid);
                se.setProbability(sse.getProbability());
                se.setNewRate(sse.getNewRate());
-           } else {
-               se = new ScheduleEdge(ctarget, "transmit", sse.getFstate(), false, gid);//new ScheduleEdge(ctarget, "transmit", sse.getClassDescriptor(), false, gid);
+               break;
+           } 
+           case ScheduleEdge.TRANSEDGE: {
+               se = new ScheduleEdge(ctarget, "transmit", sse.getFstate(), sse.getType(), gid);//new ScheduleEdge(ctarget, "transmit", sse.getClassDescriptor(), false, gid);
+               break;
+           }
+           /*case ScheduleEdge.ASSOCEDGE: {
+               //TODO
+               se = new ScheduleEdge(ctarget, "associate", sse.getFstate(), sse.getType(), gid);//new ScheduleEdge(ctarget, "transmit", sse.getClassDescriptor(), false, gid);
+               break;
+           }*/
            }
            se.setSourceCNode(sourcecn2cn.get(sse.getSourceCNode()));
            se.setTargetCNode(targetcn2cn.get(sse.getTargetCNode()));
@@ -859,22 +1115,37 @@ public class ScheduleAnalysis {
        for(int i = 0; i < toMerge.size(); i++) {
            ScheduleEdge sEdge = toMerge.elementAt(i);
            // merge this edge
-           if(sEdge.getIsNew()) {
-               ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
-           } else {
+           switch(sEdge.getType()) {
+           case ScheduleEdge.NEWEDGE: {
                try {
-                   ((ScheduleNode)sEdge.getSource()).mergeTransEdge(sEdge);
+                   ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
                } catch(Exception e) {
                    e.printStackTrace();
                    System.exit(-1);
                }
+               break;
+           } 
+           case ScheduleEdge.TRANSEDGE: {
+               try {
+                   ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
+               } catch(Exception e) {
+                   e.printStackTrace();
+                   System.exit(-1);
+               }
+               break;
+           }
+           /*case ScheduleEdge.ASSOCEDGE: {
+               // TODO
+               +
+           }*/
            }
            result.removeElement(sEdge.getTarget());
-           if(sEdge.getIsNew()) {
+           if(ScheduleEdge.NEWEDGE == sEdge.getType()) {
                // As se has been changed into an internal edge inside a ScheduleNode, 
                // change the source and target of se from original ScheduleNodes into ClassNodes.
                sEdge.setTarget(sEdge.getTargetCNode());
                sEdge.setSource(sEdge.getSourceCNode());
+               sEdge.getTargetCNode().addEdge(sEdge);
            } 
        }
        toMerge = null;
index 2ffcd67bb4a17e6a6c5b94762121a60675a49958..6797079eb32bdfe42a8b8189be826d5ce3bd52dc 100644 (file)
@@ -2,244 +2,225 @@ 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 int uid;
-    private int gid;
-    private static int nodeID=0;
-
-    private String label;
-    //private final ClassDescriptor cd;
-    private final FlagState fstate;
-    private boolean isNew = true;
-    
-    private FlagState targetFState;
+
+    public final static int NEWEDGE = 0;
+    public final static int TRANSEDGE = 1;
+    public final static int ASSOCEDGE = 2;
+
+    protected int uid;
+    protected int gid;
+    protected static int nodeID=0;
+
+    protected String label;
+    protected final FlagState fstate;
+    protected int type; // 0--new edge: indicate creating new objects
+                        // 1--transmit edge: indicate transimitting an existing object
+                        // 2-- associate edge: indicate association with another object in that they are both parameters of one task
+
+    protected FlagState targetFState; // associate edge's targetFState is always null
+
     private ClassNode sourceCNode;
     private ClassNode targetCNode;
-    
+
     private int probability;
     private int transTime;
     private int listExeTime;
-    
+
     private FEdge fedge;
     private int newRate;
-    
+
     private boolean isclone;
-    
+
     /** Class Constructor
      * 
      */
-    public ScheduleEdge(ScheduleNode target, String label, /*ClassDescriptor cd,*/FlagState fstate, int gid) {
-       super(target);
-       this.uid = ScheduleEdge.nodeID++;
-       this.gid = gid;
-       this.fedge = null;
-       this.targetFState = null;
-       this.sourceCNode = null;
-       this.targetCNode = null;
-       this.label = label;
-       //this.cd = cd;
-       this.fstate = fstate;
-       this.newRate = -1;
-       this.probability = 100;
-       this.transTime = -1;
-       this.listExeTime = -1;
-       this.isclone = false;
-    }
-    
-    public ScheduleEdge(ScheduleNode target, String label, /*ClassDescriptor cd,*/FlagState fstate, boolean isNew, int gid) {
-       super(target);
-       this.uid = ScheduleEdge.nodeID++;
-       this.gid = gid;
-       this.fedge = null;
-       this.targetFState = null;
-       this.sourceCNode = null;
-       this.targetCNode = null;
-       this.label = label;
-       //this.cd = cd;
-       this.fstate = fstate;
-       this.newRate = -1;
-       this.probability = 100;
-       this.transTime = -1;
-       this.listExeTime = -1;
-       this.isNew = isNew;
-       this.isclone = false;
-    }
-    
-    public boolean isclone() {
-        return isclone;
-    }
-
-    public void setIsclone(boolean isclone) {
-        this.isclone = isclone;
-    }
-
-    public void setTarget(GraphNode sn) {
-       this.target = sn;
-    }
-    
-    public String getLabel() {
-       String completeLabel = label;
-       if(isNew) {
-           completeLabel += ":" + Integer.toString(this.newRate);
-       }
-       completeLabel += ":(" + Integer.toString(this.probability) + "%)" + ":[" + Integer.toString(this.transTime) + "]";
-       return completeLabel;
-    }
-    
-    /*public ClassDescriptor getClassDescriptor() {
-       return cd;
-    }*/
-    
-    public FlagState getFstate() {
-        return fstate;
-    }
-    
-    public boolean getIsNew() {
-       return this.isNew;
-    }
-    
-    public FEdge getFEdge() {
-       return this.fedge;
-    }
-    
-    public void setFEdge(FEdge fEdge) {
-       this.fedge = fEdge;
-    }
-    
-    public FlagState getSourceFState() {
-       if(this.fedge == null) {
-           return null;
-       }
-       return (FlagState)this.fedge.getTarget();
-    }
-    
-    public void setTargetFState(FlagState targetFState) {
-       this.targetFState = targetFState;
-    }
-    
-    public FlagState getTargetFState() {
-       return this.targetFState;
-    }
-    
-    public int getProbability() {
-       return this.probability;
-    }
-    
-    public int getNewRate() {
-       return this.newRate;
-    }
-    
-    public ClassNode getSourceCNode() {
-       return this.sourceCNode;
-    }
-    
-    public void setSourceCNode(ClassNode sourceCNode) {
-       this.sourceCNode = sourceCNode;
-    }
-    
-    public ClassNode getTargetCNode() {
-       return this.targetCNode;
-    }
-    
-    public void setTargetCNode(ClassNode targetCNode) {
-       this.targetCNode = targetCNode;
-       this.transTime = targetCNode.getTransTime();
-    }
-       
-    public boolean equals(Object o) {
-        if (o instanceof ScheduleEdge) {
-           ScheduleEdge e=(ScheduleEdge)o;
-           if(e.gid == this.gid) {
-               if(e.uid != this.uid) {
-                   return false;
-               }
-           }
-           if ((e.label.equals(label))&&
-               (e.target.equals(target))&&
-               (e.source.equals(source)) &&
-               //(e.cd.equals(cd)) &&  
-               (e.fstate.equals(fstate)) &&
-               (e.sourceCNode.equals(sourceCNode)) &&
-               (e.targetCNode.equals(targetCNode)) &&
-               (e.newRate == newRate) && 
-               (e.probability == probability) && 
-               (e.isNew == isNew) && 
-               (e.transTime == transTime) && 
-               (e.listExeTime == listExeTime))
-               if(e.targetFState != null) {
-                   if(!e.targetFState.equals(targetFState)) {
-                       return false;
-                   }
-               } else if(this.targetFState != null) {
-                   return false;
-               } 
-               if(e.fedge != null) {
-                   return e.fedge.equals(fedge);
-               } else if(this.fedge == null) {
-                   return true;
-               } 
-        }
-        return false;
-    }
-    
-    public int hashCode(){
-       int hashcode = gid^uid^label.hashCode()^target.hashCode()^source.hashCode()^fstate.hashCode()^//cd.hashCode()^
-                       sourceCNode.hashCode()^targetCNode.hashCode()^newRate^probability^
-                       Boolean.toString(isNew).hashCode()^transTime^listExeTime;
-       if(targetFState != null) {
-           hashcode ^= targetFState.hashCode();
-       }
-       if(fedge != null) {
-           hashcode ^= fedge.hashCode();
-       }
-       return hashcode;
-    }
-    
-    public void setProbability(int prob) {
-       this.probability = prob;
-    }
-    
-    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;
-    }
+     public ScheduleEdge(ScheduleNode target, String label, FlagState fstate, int type, int gid) {
+        super(target);
+        this.uid = ScheduleEdge.nodeID++;
+        this.gid = gid;
+        this.fedge = null;
+        this.targetFState = null;
+        this.sourceCNode = null;
+        this.targetCNode = null;
+        this.label = label;
+        this.fstate = fstate;
+        this.newRate = -1;
+        this.probability = 100;
+        this.transTime = -1;
+        this.listExeTime = -1;
+        this.isclone = false;
+        this.type = type;
+     }
+
+     public boolean isclone() {
+        return isclone;
+     }
+
+     public void setIsclone(boolean isclone) {
+        this.isclone = isclone;
+     }
+
+     public void setTarget(GraphNode sn) {
+        this.target = sn;
+     }
+     
+     public int getType() {
+        return type;
+     }
+
+     public String getLabel() {
+        String completeLabel = label;
+        if(ScheduleEdge.NEWEDGE == this.type) {
+            completeLabel += ":" + Integer.toString(this.newRate);
+        }
+        completeLabel += ":(" + Integer.toString(this.probability) + "%)" + ":[" + Integer.toString(this.transTime) + "]";
+        return completeLabel;
+     }
+
+     public FlagState getFstate() {
+        return fstate;
+     }
+
+     public FEdge getFEdge() {
+        return this.fedge;
+     }
+
+     public void setFEdge(FEdge fEdge) {
+        this.fedge = fEdge;
+     }
+
+     public FlagState getSourceFState() {
+        if(this.fedge == null) {
+            return null;
+        }
+        return (FlagState)this.fedge.getTarget();
+     }
+
+     public void setTargetFState(FlagState targetFState) {
+        this.targetFState = targetFState;
+     }
+
+     public FlagState getTargetFState() {
+        return this.targetFState;
+     }
+
+     public int getProbability() {
+        return this.probability;
+     }
+
+     public int getNewRate() {
+        return this.newRate;
+     }
+
+     public ClassNode getSourceCNode() {
+        return this.sourceCNode;
+     }
+
+     public void setSourceCNode(ClassNode sourceCNode) {
+        this.sourceCNode = sourceCNode;
+     }
+
+     public ClassNode getTargetCNode() {
+        return this.targetCNode;
+     }
+
+     public void setTargetCNode(ClassNode targetCNode) {
+        this.targetCNode = targetCNode;
+        //this.targetCNode.getInedgeVector().addElement(this);
+        this.transTime = targetCNode.getTransTime();
+     }
+
+     public boolean equals(Object o) {
+        if (o instanceof ScheduleEdge) {
+            ScheduleEdge e=(ScheduleEdge)o;
+            if(e.gid == this.gid) {
+                if(e.uid != this.uid) {
+                    return false;
+                }
+            }
+            if ((e.label.equals(label))&&
+                    (e.target.equals(target))&&
+                    (e.source.equals(source)) && 
+                    (e.fstate.equals(fstate)) &&
+                    (e.sourceCNode.equals(sourceCNode)) &&
+                    (e.targetCNode.equals(targetCNode)) &&
+                    (e.newRate == newRate) && 
+                    (e.probability == probability) && 
+                    (e.type == type) && 
+                    (e.transTime == transTime) && 
+                    (e.listExeTime == listExeTime))
+                if(e.targetFState != null) {
+                    if(!e.targetFState.equals(targetFState)) {
+                        return false;
+                    }
+                } else if(this.targetFState != null) {
+                    return false;
+                } 
+            if(e.fedge != null) {
+                return e.fedge.equals(fedge);
+            } else if(this.fedge == null) {
+                return true;
+            } 
+        }
+        return false;
+     }
+
+     public int hashCode(){
+        int hashcode = gid^uid^label.hashCode()^target.hashCode()^source.hashCode()^fstate.hashCode()^
+                       sourceCNode.hashCode()^targetCNode.hashCode()^newRate^probability^
+                       type^transTime^listExeTime;
+        if(targetFState != null) {
+            hashcode ^= targetFState.hashCode();
+        }
+        if(fedge != null) {
+            hashcode ^= fedge.hashCode();
+        }
+        return hashcode;
+     }
+
+     public void setProbability(int prob) {
+        this.probability = prob;
+     }
+
+     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 e1fbaa7e9d8410e87865cfddc32932510daa04bf..f4f09dce81b06bef5f6874f8df9206c6b348b205 100644 (file)
@@ -16,6 +16,8 @@ public class ScheduleNode extends GraphNode implements Cloneable{
 
     private Vector<ClassNode> classNodes;
     Vector<ScheduleEdge> scheduleEdges;
+    private Vector<ScheduleEdge> associateEdges;
+    private Vector<ScheduleEdge> inassociateEdges;
     
     private int executionTime;
 
@@ -29,6 +31,8 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        this.executionTime = -1;
        this.classNodes = null;
        this.scheduleEdges = null;
+       this.associateEdges = new Vector<ScheduleEdge>();
+       this.inassociateEdges = new Vector<ScheduleEdge>();
     }
     
     public ScheduleNode(ClassNode cn, int gid) {
@@ -39,6 +43,8 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        this.classNodes.add(cn);
        this.addEdge(cn.getEdgeVector());
        this.executionTime = -1;
+       this.associateEdges = new Vector<ScheduleEdge>();
+       this.inassociateEdges = new Vector<ScheduleEdge>();
     }
    
     public int getuid() {
@@ -84,6 +90,37 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        scheduleEdges = null;
     }
     
+    public Vector getAssociateSEdges() {
+       return this.associateEdges;
+    }
+    
+    public Iterator getAssociateSEdgesIterator() {
+       return this.associateEdges.iterator();
+    }
+    
+    public void addAssociateSEdge(ScheduleEdge se) {
+       assert(ScheduleEdge.ASSOCEDGE == se.getType());
+       
+       this.associateEdges.addElement(se);
+       se.setSource(this);
+       ScheduleNode tonode=(ScheduleNode)se.getTarget();
+       tonode.addInAssociateSEdge(se);
+    }
+    
+    public Vector getInAssociateSEdges() {
+       return this.inassociateEdges;
+    }
+    
+    public Iterator getInAssociateSEdgesIterator() {
+       return this.inassociateEdges.iterator();
+    }
+    
+    public void addInAssociateSEdge(ScheduleEdge se) {
+       assert(ScheduleEdge.ASSOCEDGE == se.getType());
+       
+       this.inassociateEdges.addElement(se);
+    }
+    
     public int getExeTime() {
        if(this.executionTime == -1) {
            try {
@@ -175,15 +212,27 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        for(i = 0; i < this.scheduleEdges.size(); i++) {
            ScheduleEdge temp = this.scheduleEdges.elementAt(i);
            ScheduleEdge se = null;
-           if(!temp.getIsNew()) {
-               se = new ScheduleEdge(o, "transmit",temp.getFstate(), false, gid);//new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false, gid);
-           } else {
-               se = new ScheduleEdge(o, "new",temp.getFstate(), gid);//new ScheduleEdge(o, "new",temp.getClassDescriptor(), gid);
+           switch(temp.getType()) {
+           case ScheduleEdge.NEWEDGE: {
+               se = new ScheduleEdge(o, "new", temp.getFstate(), ScheduleEdge.NEWEDGE, gid);
+               se.setProbability(temp.getProbability());
+               se.setNewRate(temp.getNewRate());
+               break;
+           }
+           case ScheduleEdge.TRANSEDGE: {
+               se = new ScheduleEdge(o, "transmit", temp.getFstate(), ScheduleEdge.TRANSEDGE, gid);
+               se.setProbability(temp.getProbability());
+               se.setNewRate(temp.getNewRate());
+               break;
+           }
+           case ScheduleEdge.ASSOCEDGE: {
+               //TODO
+               se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
+               break;
+           }
            }
            se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
            se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
-           se.setProbability(temp.getProbability());
-           se.setNewRate(temp.getNewRate());
            se.setTransTime(temp.getTransTime());
            se.setFEdge(temp.getFEdge());
            se.setTargetFState(temp.getTargetFState());
@@ -194,56 +243,49 @@ public class ScheduleNode extends GraphNode implements Cloneable{
        o.scheduleEdges = tses;
        tcns = null;
        tses = null;
-       o.inedges = new Vector();
-       o.edges = new Vector();
-
-       return o;
-    }
-    
-    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();
        
-       for(int i = 0; i <  targetCNodes.size(); i++) {
-           targetCNodes.elementAt(i).setScheduleNode(this);
+       /*Vector<ScheduleEdge> assses = new Vector<ScheduleEdge>();
+       for(i = 0; i < this.scheduleEdges.size(); i++) {
+           ScheduleEdge temp = this.scheduleEdges.elementAt(i);
+           
+           assert(ScheduleEdge.ASSOCEDGE == temp.getType());
+           ScheduleEdge se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
+           se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
+           se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
+           se.setTransTime(temp.getTransTime());
+           se.setFEdge(temp.getFEdge());
+           se.setTargetFState(temp.getTargetFState());
+           se.setIsclone(true);
+           assses.add(se);
        }
+       o.associateEdges = assses;
+       assses = null;
        
-       if(classNodes == null) {
-           classNodes = targetCNodes;
-           scheduleEdges = targetSEdges;
-       } else {
-           if(targetCNodes.size() != 0) {
-               classNodes.addAll(targetCNodes);
-           }
-           if(targetSEdges.size() != 0) {
-               scheduleEdges.addAll(targetSEdges);
-           }
+       Vector<ScheduleEdge> assses = new Vector<ScheduleEdge>();
+       for(i = 0; i < this.scheduleEdges.size(); i++) {
+           ScheduleEdge temp = this.scheduleEdges.elementAt(i);
+           
+           assert(ScheduleEdge.ASSOCEDGE == temp.getType());
+           ScheduleEdge se = new ScheduleEdge(o, "associate", temp.getFstate(), ScheduleEdge.ASSOCEDGE, gid);
+           se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
+           se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
+           se.setTransTime(temp.getTransTime());
+           se.setFEdge(temp.getFEdge());
+           se.setTargetFState(temp.getTargetFState());
+           se.setIsclone(true);
+           assses.add(se);
        }
-       targetCNodes = null;
-       targetSEdges = null;
-       
-       scheduleEdges.add(se);
-       se.resetListExeTime();
-       se.getTarget().removeInedge(se);
-       this.removeEdge(se);
-       Iterator it_edges = se.getTarget().edges();
-       while(it_edges.hasNext()) {
-           ScheduleEdge tse = (ScheduleEdge)it_edges.next();
-           tse.setSource(this);
-           this.edges.addElement(tse);
-       }
+       o.associateEdges = assses;
+       assses = null;*/
        
-       // 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();
+       o.inedges = new Vector();
+       o.edges = new Vector();
+       o.associateEdges = new Vector<ScheduleEdge>();
+       o.inassociateEdges = new Vector<ScheduleEdge>();
+       return o;
     }
     
-    public void mergeTransEdge(ScheduleEdge se) throws Exception {
+    public void mergeSEdge(ScheduleEdge se) throws Exception { 
        ScheduleNode sn = (ScheduleNode)se.getTarget();
        Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
        Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
@@ -264,64 +306,87 @@ public class ScheduleNode extends GraphNode implements Cloneable{
            }
        }
        targetCNodes = null;
+       
+       if(ScheduleEdge.TRANSEDGE == se.getType()) {
+           sn.removeInedge(se);
+           this.removeEdge(se);
+           Iterator it_edges = sn.edges();
+           while(it_edges.hasNext()) {
+               ScheduleEdge tse = (ScheduleEdge)it_edges.next();
+               tse.setSource(this);
+               this.edges.addElement(tse);
+           }
 
-       sn.removeInedge(se);
-       this.removeEdge(se);
-       Iterator it_edges = sn.edges();
-       while(it_edges.hasNext()) {
-           ScheduleEdge tse = (ScheduleEdge)it_edges.next();
-           tse.setSource(this);
-           this.edges.addElement(tse);
-       }
+           // merge the split ClassNode of same class
+           FlagState sfs = se.getFstate();
+           FlagState tfs = se.getTargetFState();
+           ClassNode scn = se.getSourceCNode();
+           ClassNode tcn = se.getTargetCNode();
+           sfs.getEdgeVector().addAll(tfs.getEdgeVector());
+           // merge the subtree whose root is nfs from the whole flag transition tree
+           Vector<FlagState> sfss = scn.getFlagStates();
+           sfss.addAll(tcn.getFlagStates());
+           sfss.removeElement(tfs);
+           classNodes.removeElement(tcn);
+
+           // flush the exeTime of fs and its ancestors
+           sfs.setExeTime(0);
+           Queue<FlagState> toiterate = new LinkedList<FlagState>();
+           toiterate.add(sfs);
+           while(!toiterate.isEmpty()) {
+               FlagState tmpfs = toiterate.poll();
+               int ttime = tmpfs.getExeTime();
+               Iterator it_inedges = tmpfs.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);
+                   }
+               }
+           }
+           toiterate = null;
+
+           // redirct internal ScheduleEdge from tcn to scn
+           for(int i = 0; i < targetSEdges.size(); ++i) {
+               ScheduleEdge tmpse = targetSEdges.elementAt(i);
+               if(tmpse.getSourceCNode().equals(tcn)) {
+                   tmpse.setSourceCNode(scn);
+               }
+           }
+           
+           targetSEdges = null;
+           
+           // 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();
+           }
+       } else if(ScheduleEdge.NEWEDGE == se.getType()) {
+           targetSEdges = null;
        
-       // merge the split ClassNode of same class
-       FlagState sfs = se.getFstate();
-       FlagState tfs = se.getTargetFState();
-       ClassNode scn = se.getSourceCNode();
-       ClassNode tcn = se.getTargetCNode();
-       sfs.getEdgeVector().addAll(tfs.getEdgeVector());
-       // merge the subtree whose root is nfs from the whole flag transition tree
-       Vector<FlagState> sfss = scn.getFlagStates();
-       sfss.addAll(tcn.getFlagStates());
-       sfss.removeElement(tfs);
-       classNodes.removeElement(tcn);
-       
-       // flush the exeTime of fs and its ancestors
-       sfs.setExeTime(0);
-       Queue<FlagState> toiterate = new LinkedList<FlagState>();
-       toiterate.add(sfs);
-       while(!toiterate.isEmpty()) {
-           FlagState tmpfs = toiterate.poll();
-           int ttime = tmpfs.getExeTime();
-           Iterator it_inedges = tmpfs.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);
-               }
-           }
-       }
-       toiterate = null;
-       
-       // redirct internal ScheduleEdge from tcn to scn
-       for(int i = 0; i < targetSEdges.size(); ++i) {
-           ScheduleEdge tmpse = targetSEdges.elementAt(i);
-           if(tmpse.getSourceCNode().equals(tcn)) {
-               tmpse.setSourceCNode(scn);
-           }
-       }
-       targetSEdges = null;
-       
-       // 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();
+           scheduleEdges.add(se);
+           se.resetListExeTime();
+           sn.removeInedge(se);
+           this.removeEdge(se);
+           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) {
+               this.executionTime = 0;
+           }
+           this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
        }
     }
 }
index d2e60d2443a8bfb2619fbb5f4fb606b289af58c9..34b7603afa89cb816280a090041dfbae47415402 100644 (file)
@@ -1,5 +1,6 @@
 package Analysis.TaskStateAnalysis;
 
+import Analysis.Scheduling.ScheduleEdge;
 import Analysis.TaskStateAnalysis.*;
 import IR.*;
 import IR.Tree.*;
@@ -27,6 +28,7 @@ public class FlagState extends GraphNode implements Cloneable {
     public static final int KLIMIT=2;
     
     // jzhou
+    // for static scheduling
     private int executeTime;
     private int invokeNum;
     // for building multicore codes
@@ -34,6 +36,8 @@ public class FlagState extends GraphNode implements Cloneable {
     private int checkmask;
     private boolean setmask;
     private int iuid;
+    //private boolean isolate;
+    //private Vector<ScheduleEdge> allys;
 
     /** Class constructor
      *  Creates a new flagstate with all flags set to false.
@@ -51,6 +55,8 @@ public class FlagState extends GraphNode implements Cloneable {
        this.checkmask = 0;
        this.setmask = false;
        this.iuid = 0;
+       //this.isolate = true;
+       //this.allys = null;
     }
 
     /** Class constructor
@@ -422,4 +428,22 @@ public class FlagState extends GraphNode implements Cloneable {
        
        return next;
     }
+
+    /*public Vector<ScheduleEdge> getAllys() {
+        return allys;
+    }
+
+    public void addAlly(ScheduleEdge se) {
+       if(this.allys == null) {
+           assert(this.isolate == true);
+           this.isolate = false;
+           this.allys = new Vector<ScheduleEdge>();
+       }
+        this.allys.addElement(se);
+    }
+
+    public boolean isIsolate() {
+        return isolate;
+    }*/
+    
 }
index 848e81e1e17dd0f9bb8e215b65dcb788b626895f..f50802880634bb128621cb9445d26902a142b987 100644 (file)
@@ -6,6 +6,7 @@ import IR.Tree.TagExpressionList;
 import IR.*;
 import java.util.*;
 import java.io.*;
+
 import Util.Relation;
 import Analysis.TaskStateAnalysis.FlagState;
 import Analysis.TaskStateAnalysis.FlagComparator;
@@ -425,10 +426,11 @@ public class BuildCode {
            outclassdefs.println("  int flag;");
            if(!state.MULTICORE) {
                outclassdefs.println("  void * flagptr;");
-           } /*else {
-               outclassdefs.println("  int corenum;");
-               outclassdefs.println("  int flagptr;");
-           }*/
+           } else {
+               outclassdefs.println("  int isolate;"); // indicate if this object is shared or not
+               outclassdefs.println("  int version;");
+               outclassdefs.println("  struct ___Object___ * original;");
+           }
            if(state.OPTIONAL){
                outclassdefs.println("  int numfses;");
                outclassdefs.println("  int * fses;");
@@ -1015,9 +1017,11 @@ public class BuildCode {
            classdefout.println("  int flag;");
            if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
                classdefout.println("  void * flagptr;");
-           } /*else {
-               classdefout.println("  int flagptr;");
-           }*/
+           } else if (state.MULTICORE){
+               classdefout.println("  int isolate;"); // indicate if this object is shared or not
+               classdefout.println("  int version;");
+               classdefout.println("  struct ___Object___ * original;");
+           }
            if (state.OPTIONAL){
                classdefout.println("  int numfses;");
                classdefout.println("  int * fses;");
@@ -2087,6 +2091,10 @@ public class BuildCode {
                output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
            }
        }
+       if(state.MULTICORE) {
+           output.println("   " + generateTemp(fm,fn.getDst(),lb)+"->isolate = 1;");
+           output.println("   " + generateTemp(fm,fn.getDst(),lb)+"->version = 0;");
+       }
        if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
            String revertptr=generateTemp(fm, reverttable.get(lb),lb);
            output.println("trans->revertlist="+revertptr+";");
@@ -2170,14 +2178,15 @@ public class BuildCode {
            output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
     }
 
-    private void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
+    protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
        if (frn.getReturnTemp()!=null) {
            if (frn.getReturnTemp().getType().isPtr())
                output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
            else
                output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
-       } else
+       } else {
            output.println("return;");
+       }
     }
 
     //private void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
@@ -2794,6 +2803,9 @@ public class BuildCode {
        
        return l;
     }
+    
+    protected void outputTransCode(PrintWriter output) {
+    }
 }
         
 
index efa0031c3b4963f80f0a641cfd56503713fd609e..8665dfddd078416c43f92d25fd712e471e6fa95b 100644 (file)
@@ -49,6 +49,16 @@ public class BuildCodeMultiCore extends BuildCode {
        this.currentSchedule = null;
        this.fsate2qnames = null;
        this.startupcorenum = 0;
+       
+       // sometimes there are extra cores then needed in scheduling
+       // TODO
+       // currently, it is guaranteed that in scheduling, the corenum
+       // is started from 0 and continuous.
+       // MAY need modification here in the future when take hardware
+       // information into account.
+       if(this.scheduling.size() < this.coreNum) {
+           this.coreNum = this.scheduling.size();
+       }
     }
 
     public void buildCode() {
@@ -482,6 +492,7 @@ public class BuildCodeMultiCore extends BuildCode {
        outtask.println("#define _TASK_H");
        outtask.println("#include \"ObjectHash.h\"");
        outtask.println("#include \"structdefs.h\"");
+       outtask.println("#include \"Queue.h\"");
        outtask.println();
        outtask.println("struct tagobjectiterator {");
        outtask.println("  int istag; /* 0 if object iterator, 1 if tag iterator */");
@@ -630,6 +641,7 @@ public class BuildCodeMultiCore extends BuildCode {
            TempDescriptor temp = fm.getParameter(i);
            output.println("   int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
               "->flag;");
+           output.println("   ++" + super.generateTemp(fm, temp, lb)+"->version;");
        }
 
        /* Assign labels to FlatNode's if necessary.*/
@@ -645,6 +657,11 @@ public class BuildCodeMultiCore extends BuildCode {
            else
                output.println("checkcollect(&"+localsprefix+");");
        }*/
+       
+       /* Create queues to store objects need to be transferred to other cores and their destination*/
+       output.println("   struct Queue * totransobjqueue = createQueue();");
+       output.println("   struct Queue * desqueue = createQueue();");
+       output.println("int tmpint = 0;");
 
        /* Do the actual code generation */
        FlatNode current_node=null;
@@ -670,6 +687,7 @@ public class BuildCodeMultiCore extends BuildCode {
                output.print("   ");
                super.generateFlatNode(fm, lb, current_node, output);
                if (current_node.kind()!=FKind.FlatReturnNode) {
+                   outputTransCode(output);
                    output.println("   return;");
                }
                current_node=null;
@@ -695,6 +713,7 @@ public class BuildCodeMultiCore extends BuildCode {
                    current_node=current_node.getNext(0);
            } else throw new Error();
        }
+       
        output.println("}\n\n");
     }
 
@@ -867,7 +886,7 @@ public class BuildCodeMultiCore extends BuildCode {
            for(int i=0;i<fm.numTags();i++) {
                TempDescriptor temp=fm.getTag(i);
                int offset=i+objectparams.numPrimitives();
-               output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
+               output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];");// add i to fix bugs of duplicate definition of tags
            }
 
            if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
@@ -885,7 +904,8 @@ public class BuildCodeMultiCore extends BuildCode {
            Vector<FlagState> initfstates = ffan.getInitFStates(cd);
            for(int i = 0; i < initfstates.size(); ++i) {
                FlagState tmpFState = initfstates.elementAt(i);
-               QueueInfo qinfo = outputqueues(tmpFState, num, output);
+               
+               QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
                output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
                               ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname + 
                               ", " + qinfo.length + ");");
@@ -926,19 +946,25 @@ public class BuildCodeMultiCore extends BuildCode {
                }
            }
        }
+       boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
+                               // reside on multiple cores
        if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
            // ServerSocket object will always reside on current core
            for(int j = 0; j < targetFStates.length; ++j) {
                if(initfstates != null) {
                    FlagState fs = initfstates.elementAt(j);
+                   //isolate = this.currentSchedule.getAllyCoreTable().keySet().contains(fs);
                    output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
                            + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
                }
                Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
                for(int i = 0; i < tmpfstates.size(); ++i) {
                    FlagState tmpFState = tmpfstates.elementAt(i);
+                   // TODO 
+                   // may have bugs here
                    output.println("/* reside on this core*");
-                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", objq4socketobj[corenum], numqueues4socketobj[corenum]);");
+                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+                   //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", objq4socketobj[corenum], numqueues4socketobj[corenum]);");
                    //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
                }
                if(initfstates != null) {
@@ -952,14 +978,34 @@ public class BuildCodeMultiCore extends BuildCode {
        int num = this.currentSchedule.getCoreNum();
        Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
        for(int j = 0; j < targetFStates.length; ++j) {
+           FlagState fs = null;
            if(initfstates != null) {
-               FlagState fs = initfstates.elementAt(j);
+               fs = initfstates.elementAt(j);
                output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
                        + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
            }
            Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
            for(int i = 0; i < tmpfstates.size(); ++i) {
                FlagState tmpFState = tmpfstates.elementAt(i);
+               
+               if(this.currentSchedule.getAllyCoreTable() == null) {
+                   isolate = true;
+               } else {
+                   isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) || 
+                               (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
+               }
+               /*if(isolate) {
+                   output.println(super.generateTemp(fm, temp, lb) + "->isolate = 1;"); // not shared object
+               } else {*/
+               if(!isolate) {
+                   // indentify this object as a shared object
+                   // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object 
+                   // is shared, it maybe shared all the time afterwards
+                   output.println(super.generateTemp(fm, temp, lb) + "->isolate = 0;"); 
+                   output.println(super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
+               }
+               
+               Vector<Integer> sendto = new Vector<Integer>();
                Queue<Integer> queue = null;
                if(targetCoreTbl != null) {
                    queue = targetCoreTbl.get(tmpFState);
@@ -984,15 +1030,29 @@ public class BuildCodeMultiCore extends BuildCode {
                            targetcore = (Integer)cores[k];
                            if(targetcore.intValue() == num) {
                                output.println("/* reside on this core*/");
-                               QueueInfo qinfo = outputqueues(tmpFState, num, output);
-                               output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname + 
-                                              ", " + qinfo.length + ");");
+                               if(isolate) {
+                                   QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
+                                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname + 
+                                           ", " + qinfo.length + ");");
+                               } else {
+                                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+                               }
 
                                //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
                            } else {
+                               if(!isolate) {
+                                   output.println("/* possibly needed by multi-parameter tasks on this core*/");
+                                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+                               }
                                output.println("/* transfer to core " + targetcore.toString() + "*/");
                                // method call of transfer objects
-                               output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+                               //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+                               // enqueue this object and its destination
+                               output.println(";");
+                               output.println("tmpint = "+targetcore.toString()+";");
+                               output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
+                               output.println("addNewItem(desqueue, (void *)tmpint);");
+                               sendto.add(targetcore);
                                //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + 
                                //             ", \"" + targetcore.toString() + "\"" + ");");
                            }
@@ -1000,9 +1060,19 @@ public class BuildCodeMultiCore extends BuildCode {
                        }
                        output.println("}");
                    } else {
+                       if(!isolate) {
+                           output.println("/* possibly needed by multi-parameter tasks on this core*/");
+                           output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+                       }
                        output.println("/* transfer to core " + targetcore.toString() + "*/");
                        // method call of transfer objectts
-                       output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+                       //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + ");");
+                       // enqueue this object and its destination
+                       output.println(";");
+                       output.println("tmpint = "+targetcore.toString()+";");
+                       output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
+                       output.println("addNewItem(desqueue, (void *)tmpint);");
+                       sendto.add(targetcore);
                        //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcore.toString() + 
                        //             ", \"" + targetcore.toString() + "\"" + ");");
                    }
@@ -1011,26 +1081,54 @@ public class BuildCodeMultiCore extends BuildCode {
                } else {
                    // this object will reside on current core
                    output.println("/* reside on this core*/");
-                   QueueInfo qinfo = outputqueues(tmpFState, num, output);
-                   output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname + 
-                                  ", " + qinfo.length + ");");
+                   if(isolate) {
+                       QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
+                       output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname + 
+                               ", " + qinfo.length + ");");
+                   } else {
+                       output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
+                   }
 
                    //output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+");");
                }
+               
+               // codes for multi-params tasks
+               if(!isolate) {
+                   // flagstate associated with some multi-params tasks
+                   // need to be send to other cores
+                   Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
+                   output.println("/* send the shared object to possible queues on other cores*/");
+                   for(int k = 0; k < targetcores.size(); ++k) {
+                       //QueueInfo qinfo = outputqueues(tmpFState, num, output);
+                       // TODO
+                       // add the information of exactly which queue
+                       if(!sendto.contains(targetcores.elementAt(i))) {
+                           // previously not sended to this target core
+                           //output.println("transferObject("+super.generateTemp(fm, temp, lb)+", " + targetcores.elementAt(i).toString() + ");");
+                           // enqueue this object and its destination
+                           output.println(";");
+                           output.println("tmpint = "+targetcores.elementAt(i).toString()+";");
+                           output.println("addNewItem(totransobjqueue, (void*)" +super.generateTemp(fm, temp, lb) + ");");
+                           output.println("addNewItem(desqueue, (void *)tmpint);");
+                       }
+                   }
+               }
            }
+           
            if(initfstates != null) {
                output.println("}");
            }
        }
     }
     
-    private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output) {
+    private QueueInfo outputqueues(FlagState tmpFState, int num, PrintWriter output, boolean isEnqueue) {
        // queue array
        QueueInfo qinfo = new QueueInfo();
        output.println(";");
        qinfo.qname  = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
        output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
        Iterator it_edges = tmpFState.getEdgeVector().iterator();
+       Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
        Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
        Vector<Integer> indexes = new Vector<Integer>();
        boolean comma = false;
@@ -1039,17 +1137,19 @@ public class BuildCodeMultiCore extends BuildCode {
            FEdge fe = (FEdge)it_edges.next();
            TaskDescriptor td = fe.getTask();
            int paraindex = fe.getIndex();
-           if((!tasks.contains(td)) || 
-                   ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
-               tasks.addElement(td);
-               indexes.addElement(paraindex);
-               if(comma) {
-                   output.println(",");
-               } else {
-                   comma = true;
+           if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
+               if((!tasks.contains(td)) || 
+                       ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
+                   tasks.addElement(td);
+                   indexes.addElement(paraindex);
+                   if(comma) {
+                       output.println(",");
+                   } else {
+                       comma = true;
+                   }
+                   output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
+                   ++qinfo.length;
                }
-               output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
-               ++qinfo.length;
            }
        }
        output.println("};");
@@ -1079,4 +1179,30 @@ public class BuildCodeMultiCore extends BuildCode {
        }
        throw new Error();
     }
+    
+    protected void outputTransCode(PrintWriter output) {
+       output.println("while(0 == isEmpty(totransobjqueue)) {");
+       output.println("   struct QueueItem * totransitem = getTail(totransobjqueue);");
+       output.println("   struct QueueItem * desitem = getTail(desqueue);");
+       output.println("   transferObject(totransitem->objectptr, (int)desitem->objectptr);");
+       output.println("   removeItem(totransobjqueue, totransitem);");
+       output.println("   removeItem(desqueue, desitem);");
+       output.println("}");
+       output.println("freeQueue(totransobjqueue);");
+       output.println("freeQueue(desqueue);");
+    }
+    
+    protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
+       if (frn.getReturnTemp()!=null) {
+           if (frn.getReturnTemp().getType().isPtr())
+               output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
+           else
+               output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
+       } else {
+           if(fm.getTask() != null) {
+               outputTransCode(output);
+           }
+           output.println("return;");
+       }
+    }
 }
\ No newline at end of file
index 98070b7fcd52425aa229eefcec5faacf5b061c57..a460cc98c39828d6dcb2e97a9164c142ede8a129 100644 (file)
@@ -201,6 +201,20 @@ public class BuildFlat {
            FlatNew fn=new FlatNew(td, out_temp, con.isGlobal());
            TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
            FlatNode last=fn;
+           // Build arguments
+           for(int i=0;i<con.numArgs();i++) {
+               ExpressionNode en=con.getArg(i);
+               TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
+               temps[i]=tmp;
+               NodePair np=flattenExpressionNode(en, tmp);
+               last.addNext(np.getBegin());
+               last=np.getEnd();
+           }
+           MethodDescriptor md=con.getConstructor();
+           //Call to constructor
+           FlatCall fc=new FlatCall(md, null, out_temp, temps);
+           last.addNext(fc);
+           last=fc;
            if (td.getClassDesc().hasFlags()) {
                //          if (con.getFlagEffects()!=null) {
                FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT);
@@ -223,20 +237,6 @@ public class BuildFlat {
                last.addNext(ffan);
                last=ffan;
            }
-           //Build arguments
-           for(int i=0;i<con.numArgs();i++) {
-               ExpressionNode en=con.getArg(i);
-               TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
-               temps[i]=tmp;
-               NodePair np=flattenExpressionNode(en, tmp);
-               last.addNext(np.getBegin());
-               last=np.getEnd();
-           }
-           MethodDescriptor md=con.getConstructor();
-           //Call to constructor
-           FlatCall fc=new FlatCall(md, null, out_temp, temps);
-           last.addNext(fc);
-           last=fc;
            return new NodePair(fn,last); 
        } else {
            FlatNode first=null;
index a46cca8253f35ac80d147011014c73325ee38ee4..81c719c4ae36c72df4643751dd00127d0c772ba2 100644 (file)
@@ -338,9 +338,9 @@ public class Main {
              scheduleAnalysis.schedule();
              
              //simulate these schedulings
-             ScheduleSimulator scheduleSimulator = new ScheduleSimulator(scheduleAnalysis.getCoreNum(), state, ta);
+             //ScheduleSimulator scheduleSimulator = new ScheduleSimulator(scheduleAnalysis.getCoreNum(), state, ta);
              Iterator it_scheduling = scheduleAnalysis.getSchedulingsIter();
-             int index = 0;
+             /*int index = 0;
              Vector<Integer> selectedScheduling = new Vector<Integer>();
              int processTime = Integer.MAX_VALUE;
              while(it_scheduling.hasNext()) {
@@ -360,7 +360,7 @@ public class Main {
              for(int i = 0; i < selectedScheduling.size(); i++) {
                  System.out.print(selectedScheduling.elementAt(i) + ", ");
              }
-             System.out.println();
+             System.out.println();*/
              
              /*ScheduleSimulator scheduleSimulator = new ScheduleSimulator(4, state, ta);
              Vector<Schedule> scheduling = new Vector<Schedule>();
index 5a8da1fa9157c9017707b64724604935bf918d2c..0e3c42e8e5af24b4a56b68de3816b0814fb3ddd1 100644 (file)
@@ -5,7 +5,7 @@
 #endif
 
 struct Queue * createQueue() {
-  return RUNMALLOC(sizeof(struct Queue));
+  return (struct Queue *)RUNMALLOC(sizeof(struct Queue));
 }
 
 void freeQueue(struct Queue * q) {
index cdffe9edfa6320ebdeb065427cb336759e7797d7..283f585ee8c320ad1bd59fa982cef14a3532219c 100644 (file)
@@ -63,13 +63,21 @@ struct thread_data {
 struct thread_data thread_data_array[NUMCORES];
 mqd_t mqd[NUMCORES];
 static pthread_key_t key;
+static struct RuntimeHash* locktbl;
+static pthread_rwlock_t rwlock_tbl;
+static pthread_rwlock_t rwlock_init;
+#endif
 bool transStallMsg(int targetcore);
 void transTerminateMsg(int targetcore);
 void run(void * arg);
-#endif
+bool getreadlock(void* ptr);
+void releasereadlock(void* ptr);
+bool getwritelock(void* ptr);
+void releasewritelock(void* ptr);
 
 int main(int argc, char **argv) {
 #ifdef THREADSIMULATE
+       errno = 0;
        int tids[NUMCORES];
        int rc[NUMCORES];
        pthread_t threads[NUMCORES];
@@ -106,11 +114,22 @@ int main(int argc, char **argv) {
                int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
                mq_unlink(path);
                mqd[i]= mq_open(path, oflags, omodes, NULL);
+               if(mqd[i] == -1) {
+                       printf("[Main] mq_open %s fails: %d, error: %s\n", path, mqd[i], strerror(errno));
+                       exit(-1);
+               } else {
+                       printf("[Main] mq_open %s returns: %d\n", path, mqd[i]);
+               }
        }
 
        // create the key
        pthread_key_create(&key, NULL);
 
+       // create the lock table and initialize its mutex
+       locktbl = allocateRuntimeHash(20);
+       int rc_locktbl = pthread_rwlock_init(&rwlock_tbl, NULL);
+       printf("[Main] initialize the rwlock for lock table: %d error: \n", rc_locktbl, strerror(rc_locktbl));
+
 /*     if(argc < 2) {
                printf("Usage: <bin> <corenum>\n");
                fflush(stdout);
@@ -133,10 +152,10 @@ int main(int argc, char **argv) {
                thread_data_array[i].argv = argv;
                thread_data_array[i].numsendobjs = 0;
                thread_data_array[i].numreceiveobjs = 0;
-               printf("In main: creating thread %d\n", i);
+               printf("[main] creating thread %d\n", i);
                rc[i] = pthread_create(&threads[i], NULL, run, (void *)&thread_data_array[i]);
         if (rc[i]){
-                       printf("ERROR; return code from pthread_create() is %d\n", rc[i]);
+                       printf("[main] ERROR; return code from pthread_create() is %d\n", rc[i]);
                        fflush(stdout);
                        exit(-1);
                }
@@ -160,7 +179,7 @@ void run(void* arg) {
        pthread_setspecific(key, (void *)my_tdata->corenum);
        int argc = my_tdata->argc;
        char** argv = my_tdata->argv;
-       printf("Thread %d runs: %x\n", my_tdata->corenum, (int)pthread_self());
+       printf("[run, %d] Thread %d runs: %x\n", my_tdata->corenum, my_tdata->corenum, (int)pthread_self());
        fflush(stdout);
 
 #endif
@@ -199,7 +218,7 @@ void run(void* arg) {
   while(true) {
          switch(receiveObject()) {
                  case 0: {
-                                         printf("[run] receive an object\n");
+                                         printf("[run, %d] receive an object\n", numofcore);
                                          sendStall = false;
                                          // received an object
                                          // check if there are new active tasks can be executed
@@ -207,7 +226,7 @@ void run(void* arg) {
                                          break;
                                  }
                  case 1: {
-                                         //printf("[run] no msg\n");
+                                         //printf("[run, %d] no msg\n", numofcore);
                                          // no msg received
                                          if(STARTUPCORE == numofcore) {
                                                  corestatus[numofcore] = 0;
@@ -239,7 +258,46 @@ void run(void* arg) {
                                                                          }
                                                                  }
                                                                  mq_close(mqd[corenum]);*/
-                                                                 printf("[run] terminate!\n");
+                                                                 
+                                                                 // release all locks
+                                                                 struct RuntimeIterator* it_lock = RuntimeHashcreateiterator(locktbl); 
+                                                                 while(0 != RunhasNext(it_lock)) {
+                                                                         int key = Runkey(it_lock);
+                                                                         pthread_rwlock_t* rwlock_obj = (pthread_rwlock_t*)Runnext(it_lock);
+                                                                         int rc_des = pthread_rwlock_destroy(rwlock_obj);
+                                                                         printf("[run, %d] destroy the rwlock for object: %d error: \n", numofcore, key, strerror(rc_des));
+                                                                 }
+                                                                 freeRuntimeHash(locktbl);
+                                                                 locktbl = NULL;
+                                                                 RUNFREE(it_lock);
+
+                                                                 // destroy all message queues
+                                                                 char * pathhead = "/msgqueue_";
+                                                                 int targetlen = strlen(pathhead);
+                                                                 for(i = 0; i < NUMCORES; ++i) {
+                                                                         char corenumstr[3];
+                                                                         int sourcelen = 0;
+                                                                         if(i < 10) {
+                                                                                 corenumstr[0] = i + '0';
+                                                                                 corenumstr[1] = '\0';
+                                                                                 sourcelen = 1;
+                                                                         } else if(i < 100) {
+                                                                                 corenumstr[1] = i %10 + '0';
+                                                                                 corenumstr[0] = (i / 10) + '0';
+                                                                                 corenumstr[2] = '\0';
+                                                                                 sourcelen = 2;
+                                                                         } else {
+                                                                                 printf("Error: i >= 100\n");  
+                                                                                 fflush(stdout);
+                                                                                 exit(-1);
+                                                                         }
+                                                                         char path[targetlen + sourcelen + 1];
+                                                                         strcpy(path, pathhead);
+                                                                         strncat(path, corenumstr, sourcelen);
+                                                                         mq_unlink(path);
+                                                                 }
+
+                                                                 printf("[run, %d] terminate!\n", numofcore);
                                                                  fflush(stdout);
                                                                  exit(0);
                                                          }
@@ -253,14 +311,14 @@ void run(void* arg) {
                                          break;
                                  }
                  case 2: {
-                                         printf("[run] receive a stall msg\n");
+                                         printf("[run, %d] receive a stall msg\n", numofcore);
                                          // receive a Stall Msg, do nothing
                                          assert(STARTUPCORE == numofcore); // only startup core can receive such msg
                                          sendStall = false;
                                          break;
                                  }
                 /* case 3: {
-                                         printf("[run] receive a terminate msg\n");
+                                         printf("[run, %d] receive a terminate msg\n", numofcore);
                                          // receive a terminate Msg
                                          assert(STARTUPCORE != corenum); // only non-startup core can receive such msg
                                          mq_close(mqd[corenum]);
@@ -269,7 +327,7 @@ void run(void* arg) {
                                          break;
                                  }*/
                  default: {
-                                          printf("Error: invalid message type.\n");
+                                          printf("[run, %d] Error: invalid message type.\n", numofcore);
                                           fflush(stdout);
                                           exit(-1);
                                           break;
@@ -302,6 +360,9 @@ void createstartupobject(int argc, char ** argv) {
     ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;
   }
   
+  startupobject->isolate = 1;
+  startupobject->version = 0;
+
   /* Set initialized flag for startup object */ 
   flagorandinit(startupobject,1,0xFFFFFFFF);
   enqueueObject(startupobject, NULL, 0);
@@ -683,6 +744,8 @@ void transferObject(void * obj, int targetcore) {
        //printf( "umap ok \n" );
 #endif
 
+       int numofcore = pthread_getspecific(key);
+
        // use POSIX message queue to transfer objects between cores
        mqd_t mqdnum;
        char corenumstr[3];
@@ -706,28 +769,33 @@ void transferObject(void * obj, int targetcore) {
        char path[targetlen + sourcelen + 1];
        strcpy(path, pathhead);
        strncat(path, corenumstr, sourcelen);
-       int oflags = O_WRONLY|O_CREAT|O_NONBLOCK;
+       int oflags = O_WRONLY|O_NONBLOCK;
        int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
        mqdnum = mq_open(path, oflags, omodes, NULL);
        if(mqdnum==-1) {
-               printf("[transferObject] mq_open fail: %d, error: %s\n", mqdnum, strerror(errno));
+               printf("[transferObject, %d] mq_open %s fail: %d, error: %s\n", numofcore, path, mqdnum, strerror(errno));
                fflush(stdout);
                exit(-1);
        }
+       struct ___Object___ * newobj = (struct ___Object___ *)obj;
+       if(0 == newobj->isolate) {
+               newobj = RUNMALLOC(size);
+               memcpy(newobj, obj, size);
+               newobj->original=obj;
+       }
        int ret;
        do {
-               ret=mq_send(mqdnum, obj, size, 0); // send the object into the queue
+               ret=mq_send(mqdnum, (void *)newobj, size, 0); // send the object into the queue
                if(ret != 0) {
-                       printf("[transferObject] mq_send returned: %d, error: %s\n", ret, strerror(errno));
+                       printf("[transferObject, %d] mq_send to %s returned: %d, error: %s\n", numofcore, path, ret, strerror(errno));
                }
-       }while(ret!=0);
-       int numofcore = pthread_getspecific(key);
+       }while(ret!=0); 
        if(numofcore == STARTUPCORE) {
                ++numsendobjs[numofcore];
        } else {
                ++(thread_data_array[numofcore].numsendobjs);
        }
-       printf("[transferObject] mq_send returned: $%x\n",ret);
+       printf("[transferObject, %d] mq_send to %s returned: $%x\n", numofcore, path, ret);
 #endif
 }
 
@@ -796,22 +864,22 @@ bool transStallMsg(int targetcore) {
        char path[targetlen + sourcelen + 1];
        strcpy(path, pathhead);
        strncat(path, corenumstr, sourcelen);
-       int oflags = O_WRONLY|O_CREAT|O_NONBLOCK;
+       int oflags = O_WRONLY|O_NONBLOCK;
        int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
        mqdnum = mq_open(path, oflags, omodes, NULL);
        if(mqdnum==-1) {
-               printf("[transStallMsg] mq_open fail: %d, error: %s\n", mqdnum, strerror(errno));
+               printf("[transStallMsg, %d] mq_open %s fail: %d, error: %s\n", numofcore, path, mqdnum, strerror(errno));
                fflush(stdout);
                exit(-1);
        }
        int ret;
        ret=mq_send(mqdnum, (void *)&newobj, sizeof(struct ___Object___), 0); // send the object into the queue
        if(ret != 0) {
-               printf("[transStallMsg] mq_send returned: %d, error: %s\n", ret, strerror(errno));
+               printf("[transStallMsg, %d] mq_send to %s returned: %d, error: %s\n", numofcore, path, ret, strerror(errno));
                return false;
        } else {
-               printf("[transStallMsg] mq_send returned: $%x\n", ret);
-               printf("index: %d, sendobjs: %d, receiveobjs: %d\n", newobj.flag, newobj.___cachedHash___, newobj.___cachedCode___);
+               printf("[transStallMsg, %d] mq_send to %s returned: $%x\n", numofcore, path, ret);
+               printf("<transStallMsg> to %s index: %d, sendobjs: %d, receiveobjs: %d\n", path, newobj.flag, newobj.___cachedHash___, newobj.___cachedCode___);
                return true;
        }
 #endif
@@ -851,7 +919,7 @@ void transTerminateMsg(int targetcore) {
        char path[targetlen + sourcelen + 1];
        strcpy(path, pathhead);
        strncat(path, corenumstr, sourcelen);
-       int oflags = O_WRONLY|O_CREAT|O_NONBLOCK;
+       int oflags = O_WRONLY|O_NONBLOCK;
        int omodes = S_IRWXU|S_IRWXG|S_IRWXO;
        mqdnum = mq_open(path, oflags, omodes, NULL);
        if(mqdnum==-1) {
@@ -922,12 +990,12 @@ int receiveObject() {
        //printf("msg: %s\n",msgptr);
        if(((int*)msgptr)[0] == -1) {
                // StallMsg
-               int* tmpptr = (int*)msgptr;
-               int index = tmpptr[1];
+               struct ___Object___ * tmpptr = (struct ___Object___ *)msgptr;
+               int index = tmpptr->flag;
                corestatus[index] = 0;
-               numsendobjs[index] = tmpptr[2];
-               numreceiveobjs[index] = ((int *)(msgptr + sizeof(int) * 3 + sizeof(void *)))[0];
-               printf("index: %d, sendobjs: %d, reveiveobjs: %d\n", index, numsendobjs[index], numreceiveobjs[index]);
+               numsendobjs[index] = tmpptr->___cachedHash___;
+               numreceiveobjs[index] = tmpptr->___cachedCode___;
+               printf("<receiveObject> index: %d, sendobjs: %d, reveiveobjs: %d\n", index, numsendobjs[index], numreceiveobjs[index]);
                free(msgptr);
                return 2;
        } /*else if(((int*)msgptr)[0] == -2) {
@@ -949,6 +1017,157 @@ int receiveObject() {
 #endif
 }
 
+bool getreadlock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+       int numofcore = pthread_getspecific(key);
+
+       int rc = pthread_rwlock_tryrdlock(&rwlock_tbl);
+       printf("[getreadlock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+       if(EBUSY == rc) {
+               return false;
+       }
+       if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+               // no locks for this object
+               // first time to operate on this shared object
+               // create a lock for it
+               rc = pthread_rwlock_unlock(&rwlock_tbl);
+               printf("[getreadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               pthread_rwlock_t* rwlock = (pthread_rwlock_t *)RUNMALLOC(sizeof(pthread_rwlock_t));
+               memcpy(rwlock, &rwlock_init, sizeof(pthread_rwlock_t));
+               rc = pthread_rwlock_init(rwlock, NULL);
+               printf("[getreadlock, %d] initialize the rwlock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
+               rc = pthread_rwlock_trywrlock(&rwlock_tbl);
+               printf("[getreadlock, %d] getting the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               if(EBUSY == rc) {
+                       return false;
+               } else {
+                       RuntimeHashadd(locktbl, (int)ptr, (int)rwlock);
+                       rc = pthread_rwlock_unlock(&rwlock_tbl);
+                       printf("[getreadlock, %d] release the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               }
+               //rc = pthread_rwlock_rdlock(&rwlock);
+               rc = pthread_rwlock_tryrdlock(rwlock);
+               printf("[getreadlock, %d] getting read lock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));       
+               if(EBUSY == rc) {
+                       return false;
+               } else {
+                       return true;
+               }
+       } else {
+               pthread_rwlock_t* rwlock_obj = NULL;
+               RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+               rc = pthread_rwlock_unlock(&rwlock_tbl);
+               printf("[getreadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               //int rc_obj = pthread_rwlock_rdlock(&rwlock_obj);
+               int rc_obj = pthread_rwlock_tryrdlock(rwlock_obj);
+               printf("[getreadlock, %d] getting read lock for object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+               if(EBUSY == rc_obj) {
+                       return false;
+               } else {
+                       return true;
+               }
+       }
+#endif
+}
+
+void releasereadlock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+       int numofcore = pthread_getspecific(key);
+       int rc = pthread_rwlock_rdlock(&rwlock_tbl);
+       printf("[releasereadlock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+       if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+               printf("[releasereadlock, %d] Error: try to release a lock without previously grab it\n", numofcore);
+               exit(-1);
+       }
+       pthread_rwlock_t* rwlock_obj = NULL;
+       RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+       int rc_obj = pthread_rwlock_unlock(rwlock_obj);
+       printf("[releasereadlock, %d] unlocked object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+       rc = pthread_rwlock_unlock(&rwlock_tbl);
+       printf("[releasereadlock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+#endif
+}
+
+bool getwritelock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+       int numofcore = pthread_getspecific(key);
+
+       int rc = pthread_rwlock_tryrdlock(&rwlock_tbl);
+       printf("[getwritelock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+       if(EBUSY == rc) {
+               return false;
+       }
+       if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+               // no locks for this object
+               // first time to operate on this shared object
+               // create a lock for it
+               rc = pthread_rwlock_unlock(&rwlock_tbl);
+               printf("[getwritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               pthread_rwlock_t* rwlock = (pthread_rwlock_t *)RUNMALLOC(sizeof(pthread_rwlock_t));
+               memcpy(rwlock, &rwlock_init, sizeof(pthread_rwlock_t));
+               rc = pthread_rwlock_init(rwlock, NULL);
+               printf("[getwritelock, %d] initialize the rwlock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));
+               rc = pthread_rwlock_trywrlock(&rwlock_tbl);
+               printf("[getwritelock, %d] getting the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               if(EBUSY == rc) {
+                       return false;
+               } else {
+                       RuntimeHashadd(locktbl, (int)ptr, (int)rwlock);
+                       rc = pthread_rwlock_unlock(&rwlock_tbl);
+                       printf("[getwritelock, %d] release the write lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               }
+               //rc = pthread_rwlock_wrlock(rwlock);
+               rc = pthread_rwlock_trywrlock(rwlock);
+               printf("[getwritelock, %d] getting write lock for object %d: %d error: \n", numofcore, (int)ptr, rc, strerror(rc));     
+               if(EBUSY == rc) {
+                       return false;
+               } else {
+                       return true;
+               }
+       } else {
+               pthread_rwlock_t* rwlock_obj = NULL;
+               RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+               rc = pthread_rwlock_unlock(&rwlock_tbl);
+               printf("[getwritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+               //int rc_obj = pthread_rwlock_wrlock(rwlock_obj);
+               int rc_obj = pthread_rwlock_trywrlock(rwlock_obj);
+               printf("[getwritelock, %d] getting write lock for object %d: %d error: \n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+               if(EBUSY == rc_obj) {
+                       return false;
+               } else {
+                       return true;
+               }
+       }
+
+#endif
+}
+
+void releasewritelock(void * ptr) {
+#ifdef RAW
+
+#elif defined THREADSIMULATE
+       int numofcore = pthread_getspecific(key);
+       int rc = pthread_rwlock_rdlock(&rwlock_tbl);
+       printf("[releasewritelock, %d] getting the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+       if(!RuntimeHashcontainskey(locktbl, (int)ptr)) {
+               printf("[releasewritelock, %d] Error: try to release a lock without previously grab it\n", numofcore);
+               exit(-1);
+       }
+       pthread_rwlock_t* rwlock_obj = NULL;
+       RuntimeHashget(locktbl, (int)ptr, (int*)&rwlock_obj);
+       int rc_obj = pthread_rwlock_unlock(rwlock_obj);
+       printf("[releasewritelock, %d] unlocked object %d: %d error:\n", numofcore, (int)ptr, rc_obj, strerror(rc_obj));
+       rc = pthread_rwlock_unlock(&rwlock_tbl);
+       printf("[releasewritelock, %d] release the read lock for locktbl: %d error: \n", numofcore, rc, strerror(rc));
+#endif
+}
+
 int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
   void * taskpointerarray[MAXTASKPARAMS];
   int j;
@@ -1135,9 +1354,73 @@ void executetasks() {
       int numparams=currtpd->task->numParameters;
       int numtotal=currtpd->task->numTotal;
       
+         int isolateflags[numparams];
       /* Make sure that the parameters are still in the queues */
       for(i=0;i<numparams;i++) {
        void * parameter=currtpd->parameterArray[i];
+       struct ___Object___ * tmpparam = (struct ___Object___ *)parameter;
+       if(0 == tmpparam->isolate) {
+               isolateflags[i] = 0;
+               // shared object, need to flush with current value
+               //if(!getreadlock(tmpparam->original)) {
+               //      // fail to get read lock of the original object, try this task later
+               if(!getwritelock(tmpparam->original)) {
+                       // fail to get write lock, release all obtained locks and try this task later
+                       int j = 0;
+                       for(j = 0; j < i; ++j) {
+                               if(0 == isolateflags[j]) {
+                                       releasewritelock(taskpointerarray[j]);
+                               }
+                       }
+                       genputtable(activetasks, currtpd, currtpd);
+                       goto newtask;
+               }
+               if(tmpparam->version != tmpparam->original->version) {
+                       // flush this object
+                       memcpy(tmpparam, tmpparam->original, classsize[tmpparam->type]);
+                       //releasereadlock(tmpparam->original);
+                       // fail to get write lock, release all obtained locks and try this task later
+                       int j = 0;
+                       for(j = 0; j < i; ++j) {
+                               if(0 == isolateflags[j]) {
+                                       releasewritelock(((struct ___Object___ *)taskpointerarray[j+OFFSET])->original);
+                               }
+                       }
+                       releasewritelock(tmpparam->original);
+
+                       // some task on another core has changed this object
+                       // Free up task parameter descriptor
+                       RUNFREE(currtpd->parameterArray);
+                       RUNFREE(currtpd);
+                       // dequeue this object
+#ifdef THREADSIMULATE
+                       int numofcore = pthread_getspecific(key);
+                       struct parameterwrapper ** queues = objectqueues[numofcore][tmpparam->type];
+                       int length = numqueues[numofcore][tmpparam->type];
+#else
+                       struct parameterwrapper ** queues = objectqueues[corenum][tmpparam->type];
+                       int length = numqueues[corenum][tmpparam->type];
+#endif
+                       for(j = 0; j < length; ++j) {
+                               struct parameterwrapper * pw = queues[j];
+                               if(ObjectHashcontainskey(pw->objectset, (int)tmpparam)) {
+                                       int next;
+                                       int UNUSED, UNUSED2;
+                                       int * enterflags;
+                                       ObjectHashget(pw->objectset, (int) tmpparam, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
+                                       ObjectHashremove(pw->objectset, (int)tmpparam);
+                                       if (enterflags!=NULL)
+                                               free(enterflags);
+                               }
+                       }
+                       // try to enqueue it again to check if it feeds other tasks;
+                       enqueueObject(tmpparam, NULL, 0);
+                       goto newtask;
+               }
+               //releasereadlock(tmpparam->original);
+       } else {
+               isolateflags[i] = 1;
+       }
        struct parameterdescriptor * pd=currtpd->task->descriptorarray[i];
        struct parameterwrapper *pw=(struct parameterwrapper *) pd->queue;
        int j;
@@ -1169,6 +1452,27 @@ void executetasks() {
        taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
       }
 
+        for(i = 0; i < numparams; ++i) {
+                 if(0 == isolateflags[i]) {
+                         struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
+                         // shared object, need to replace this copy with original one
+                         /*if(!getwritelock(tmpparam->original)) {
+                                 // fail to get write lock, release all obtained locks and try this task later
+                                 int j = 0;
+                                 for(j = 0; j < i; ++j) {
+                                         if(0 == isolateflags[j]) {
+                                                 releasewritelock(taskpointerarray[j]);
+                                         }
+                                 }
+                                 genputtable(activetasks, tpd, tpd);
+                                 goto newtask;
+                         }*/
+                         if(tmpparam != tmpparam->original) {
+                                 taskpointerarray[i+OFFSET] = tmpparam->original;
+                         }
+                 }
+         }
+
       {
        /* Checkpoint the state */
        forward=allocateRuntimeHash(100);
@@ -1213,6 +1517,13 @@ void executetasks() {
          } else
            ((void (*) (void **)) currtpd->task->taskptr)(taskpointerarray);
 
+         for(i = 0; i < numparams; ++i) {
+                 if(0 == isolateflags[i]) {
+                         struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
+                         releasewritelock(tmpparam);
+                 }
+         }
+
          freeRuntimeHash(forward);
          freeRuntimeHash(reverse);
          freemalloc();
@@ -1391,12 +1702,18 @@ void processtasks() {
 #endif
     int j;
 
-    /* Build iterators for parameters */
-    for(j=0;j<task->numParameters;j++) {
+       /* Build objectsets */
+       for(j=0;j<task->numParameters;j++) {
       struct parameterdescriptor *param=task->descriptorarray[j];
       struct parameterwrapper *parameter=param->queue;
          parameter->objectset=allocateObjectHash(10);
          parameter->task=task;
+    }
+
+    /* Build iterators for parameters */
+    for(j=0;j<task->numParameters;j++) {
+      struct parameterdescriptor *param=task->descriptorarray[j];
+      struct parameterwrapper *parameter=param->queue;
       builditerators(task, j, parameter);
     }
   }