From: jzhou Date: Wed, 14 May 2008 22:08:32 +0000 (+0000) Subject: Add support for multi-parameter tasks as well as tag in multi-core version X-Git-Tag: preEdgeChange~85 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a21ac2c6be7ec24af44127976a1ca3153f75516d;p=IRC.git Add support for multi-parameter tasks as well as tag in multi-core version --- diff --git a/Robust/src/Analysis/Scheduling/Schedule.java b/Robust/src/Analysis/Scheduling/Schedule.java index 3fedbb6c..246fb2ab 100644 --- a/Robust/src/Analysis/Scheduling/Schedule.java +++ b/Robust/src/Analysis/Scheduling/Schedule.java @@ -17,6 +17,8 @@ public class Schedule { private Hashtable targetFState; private Vector ancestorCores; private Vector childCores; + private Hashtable> allyCores; + private Hashtable> 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> getAllyCoreTable() { + return this.allyCores; + } + + public Vector getAllyCores(FlagState fstate) { + if(this.allyCores == null) { + return null; + } + return this.allyCores.get(fstate); + } + + public Hashtable> getTd2FsTable() { + return this.td2fs; + } + + public Vector 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>(); + } + if(!this.allyCores.containsKey(fstate)) { + this.allyCores.put(fstate, new Vector()); + } + 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>(); + } + if(!this.td2fs.containsKey(td)) { + this.td2fs.put(td, new Vector()); + } + if(!this.td2fs.get(td).contains(fstate)) { + this.td2fs.get(td).add(fstate); + } + } public Vector getTasks() { return tasks; diff --git a/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java b/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java index 937f7d42..ac476561 100644 --- a/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java +++ b/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java @@ -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 ssev = new Vector(); - Vector 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 it_tasks = (Iterator)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 fev = (Vector)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 ssev = new Vector(); + Vector 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> sn2fes = new Hashtable>(); 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 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()); } - 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 cn2cn = new Hashtable(); + private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) throws Exception { + Hashtable cn2cn = new Hashtable(); // 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 toClone = new LinkedList(); - Queue clone = new LinkedList(); - Queue qcn2cn = new LinkedList(); + Queue toClone = new LinkedList(); // all nodes to be cloned + Queue clone = new LinkedList(); //clone nodes + Queue qcn2cn = new LinkedList(); // queue of the mappings of classnodes inside cloned ScheduleNode + Vector origins = new Vector(); // queue of source ScheduleNode cloned + Hashtable sn2sn = new Hashtable(); // 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 tocn2cn = new Hashtable(); @@ -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 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 toremove = new Vector(); 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 sEdges = new Vector(); @@ -721,7 +887,17 @@ public class ScheduleAnalysis { this.schedulings = new Vector>(); } + Vector multiparamtds = new Vector(); + 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> td2cores = new Hashtable>(); // multiparam tasks reside on which cores Vector scheduleGraph = this.scheduleGraphs.elementAt(i); Vector scheduling = new Vector(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()); + } + Vector 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 cores = td2cores.get(td); + if(cores.size() == 1) { + continue; + } + for(int k = 0; k < cores.size(); ++k) { + Schedule tmpSchedule = cores.elementAt(k); + Vector 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 sourcecn2cn = sn2hash.get(csource); Hashtable 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; diff --git a/Robust/src/Analysis/Scheduling/ScheduleEdge.java b/Robust/src/Analysis/Scheduling/ScheduleEdge.java index 2ffcd67b..6797079e 100644 --- a/Robust/src/Analysis/Scheduling/ScheduleEdge.java +++ b/Robust/src/Analysis/Scheduling/ScheduleEdge.java @@ -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; + } } diff --git a/Robust/src/Analysis/Scheduling/ScheduleNode.java b/Robust/src/Analysis/Scheduling/ScheduleNode.java index e1fbaa7e..f4f09dce 100644 --- a/Robust/src/Analysis/Scheduling/ScheduleNode.java +++ b/Robust/src/Analysis/Scheduling/ScheduleNode.java @@ -16,6 +16,8 @@ public class ScheduleNode extends GraphNode implements Cloneable{ private Vector classNodes; Vector scheduleEdges; + private Vector associateEdges; + private Vector 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(); + this.inassociateEdges = new Vector(); } 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(); + this.inassociateEdges = new Vector(); } 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 targetCNodes = (Vector)((ScheduleNode)se.getTarget()).getClassNodes(); - Vector targetSEdges = (Vector)((ScheduleNode)se.getTarget()).getScheduleEdges(); - for(int i = 0; i < targetCNodes.size(); i++) { - targetCNodes.elementAt(i).setScheduleNode(this); + /*Vector assses = new Vector(); + 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 assses = new Vector(); + 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(); + o.inassociateEdges = new Vector(); + return o; } - public void mergeTransEdge(ScheduleEdge se) throws Exception { + public void mergeSEdge(ScheduleEdge se) throws Exception { ScheduleNode sn = (ScheduleNode)se.getTarget(); Vector targetCNodes = (Vector)sn.getClassNodes(); Vector targetSEdges = (Vector)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 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 toiterate = new LinkedList(); + 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 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 toiterate = new LinkedList(); - 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(); } } } diff --git a/Robust/src/Analysis/TaskStateAnalysis/FlagState.java b/Robust/src/Analysis/TaskStateAnalysis/FlagState.java index d2e60d24..34b7603a 100644 --- a/Robust/src/Analysis/TaskStateAnalysis/FlagState.java +++ b/Robust/src/Analysis/TaskStateAnalysis/FlagState.java @@ -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 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 getAllys() { + return allys; + } + + public void addAlly(ScheduleEdge se) { + if(this.allys == null) { + assert(this.isolate == true); + this.isolate = false; + this.allys = new Vector(); + } + this.allys.addElement(se); + } + + public boolean isIsolate() { + return isolate; + }*/ + } diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 848e81e1..f5080288 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -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) { + } } diff --git a/Robust/src/IR/Flat/BuildCodeMultiCore.java b/Robust/src/IR/Flat/BuildCodeMultiCore.java index efa0031c..8665dfdd 100644 --- a/Robust/src/IR/Flat/BuildCodeMultiCore.java +++ b/Robust/src/IR/Flat/BuildCodeMultiCore.java @@ -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;imaxtaskparams) @@ -885,7 +904,8 @@ public class BuildCodeMultiCore extends BuildCode { Vector 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 tmpfstates = (Vector)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> 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 tmpfstates = (Vector)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 sendto = new Vector(); Queue 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 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 residetasks = this.currentSchedule.getTasks(); Vector tasks = new Vector(); Vector indexes = new Vector(); 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 diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index 98070b7f..a460cc98 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -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 selectedScheduling = new Vector(); 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 scheduling = new Vector(); diff --git a/Robust/src/Runtime/Queue.c b/Robust/src/Runtime/Queue.c index 5a8da1fa..0e3c42e8 100644 --- a/Robust/src/Runtime/Queue.c +++ b/Robust/src/Runtime/Queue.c @@ -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) { diff --git a/Robust/src/Runtime/multicoretask.c b/Robust/src/Runtime/multicoretask.c index cdffe9ed..283f585e 100644 --- a/Robust/src/Runtime/multicoretask.c +++ b/Robust/src/Runtime/multicoretask.c @@ -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: \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(" 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(" 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;iparameterArray[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;jnumParameters;j++) { + /* Build objectsets */ + for(j=0;jnumParameters;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;jnumParameters;j++) { + struct parameterdescriptor *param=task->descriptorarray[j]; + struct parameterwrapper *parameter=param->queue; builditerators(task, j, parameter); } }