From: yeom Date: Mon, 8 Mar 2010 18:19:25 +0000 (+0000) Subject: changes. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c3629fdaa5c7afa61ca11ce498bf66776729dc3d;p=IRC.git changes. --- diff --git a/Robust/src/Analysis/MLP/ConflictGraph.java b/Robust/src/Analysis/MLP/ConflictGraph.java index dc2db0a9..a7c4c72b 100644 --- a/Robust/src/Analysis/MLP/ConflictGraph.java +++ b/Robust/src/Analysis/MLP/ConflictGraph.java @@ -16,14 +16,6 @@ import IR.Flat.TempDescriptor; public class ConflictGraph { - public static final int FINEREAD = 0; - public static final int FINEWRITE = 1; - public static final int PARENTREAD = 2; - public static final int PARENTWRITE = 3; - public static final int COARSE = 4; - public static final int PARENTCOARSE = 5; - public static final int SCC = 6; - static private int uniqueCliqueIDcount = 100; public Hashtable id2cn; @@ -191,6 +183,10 @@ public class ConflictGraph { private int determineWriteConflictsType(LiveInNode liveInNodeA, LiveInNode liveInNodeB) { + + if(liveInNodeA.getSESEIdentifier()==liveInNodeB.getSESEIdentifier()){ + return ConflictEdge.NON_WRITE_CONFLICT; + } Set liveInHrnSetA = liveInNodeA.getHRNSet(); Set liveInHrnSetB = liveInNodeB.getHRNSet(); @@ -216,6 +212,10 @@ public class ConflictGraph { } else if (isSharingReachability) { // two node share same reachability but points to different region, // then it is coarse grain conflicts +// System.out.println("##coarse:"); +// System.out.println(liveInNodeA.getSESEIdentifier()+" <-> "+liveInNodeB.getSESEIdentifier()); +// System.out.println(liveInNodeA.getID()+" <-> "+liveInNodeB.getID()); +// System.out.println("--"); return ConflictEdge.COARSE_GRAIN_EDGE; } else { // otherwise, it is not write conflicts @@ -580,7 +580,6 @@ public class ConflictGraph { addConflictEdge(conflictType, currentNode, entryNode); } - } analyzedIDSet.add(currentNode.getID() + entryNodeID); } @@ -727,8 +726,6 @@ public class ConflictGraph { Set> s = id2cn.entrySet(); Collection stallSites = conflictsMap.getStallMap().values(); - String dynID=""; - for (Iterator iterator = stallSites.iterator(); iterator.hasNext();) { StallSite stallSite = (StallSite) iterator.next(); @@ -747,50 +744,20 @@ public class ConflictGraph { ConflictEdge conflictEdge = (ConflictEdge) iter2 .next(); - int type = -1; - HashSet allocSet = new HashSet(); - - if (conflictEdge.getType() == ConflictEdge.COARSE_GRAIN_EDGE) { - type = PARENTCOARSE; - - allocSet.addAll(getAllocSet(conflictEdge - .getVertexU())); - allocSet.addAll(getAllocSet(conflictEdge - .getVertexV())); - - } else if (conflictEdge.getType() == ConflictEdge.FINE_GRAIN_EDGE) {// it - // is - // fine-grain - // edge - allocSet.addAll(getAllocSet(node)); - if (isReadOnly(node)) { - // parent fine-grain read - type = PARENTREAD; - dynID=node.getTempDescriptor().toString(); - } else { - // parent fine-grain write - type = PARENTWRITE; - dynID=node.getTempDescriptor().toString(); - } - } - - if (type > -1) { for (Iterator seseLockIter = seseLockSet .iterator(); seseLockIter.hasNext();) { SESELock seseLock = seseLockIter.next(); - if (seseLock - .containsConflictNode(stallSiteNode)) { + if (seseLock.containsConflictNode(stallSiteNode) && seseLock.containsConflictEdge(conflictEdge)) { WaitingElement newElement = new WaitingElement(); - newElement.setDynID(dynID); - newElement.setAllocList(allocSet); newElement.setWaitingID(seseLock .getID()); - newElement.setStatus(type); + if(isFineElement(newElement.getStatus())){ + newElement.setDynID(node.getTempDescriptor().toString()); + } + newElement.setStatus(seseLock.getNodeType(stallSiteNode)); waitingElementSet.add(newElement); } } - } - } } } @@ -924,7 +891,6 @@ public class ConflictGraph { public Set getWaitingElementSetBySESEID(int seseID, HashSet seseLockSet) { - HashSet waitingElementSet = new HashSet(); Set> s = id2cn.entrySet(); @@ -944,75 +910,21 @@ public class ConflictGraph { .hasNext();) { ConflictEdge conflictEdge = (ConflictEdge) iterator .next(); - int type = -1; - HashSet allocSet = new HashSet(); - HashSet connectedSet=new HashSet(); - String dynID=""; - - if (conflictEdge.getType() == ConflictEdge.COARSE_GRAIN_EDGE) { - type = COARSE; - - allocSet.addAll(getAllocSet(conflictEdge - .getVertexU())); - allocSet.addAll(getAllocSet(conflictEdge - .getVertexV())); - - } else if (conflictEdge.getType() == ConflictEdge.FINE_GRAIN_EDGE) {// it - // is - // fine-grain - // edge - allocSet.addAll(getAllocSet(node)); - if(conflictEdge.getVertexU() instanceof LiveInNode ){ - connectedSet.add(new Integer(((LiveInNode)conflictEdge.getVertexU()).getSESEIdentifier())); - } - if(conflictEdge.getVertexV() instanceof LiveInNode ){ - connectedSet.add(new Integer(((LiveInNode)conflictEdge.getVertexV()).getSESEIdentifier())); - } - - - if (isReadOnly(node)) { - // fine-grain read - type = FINEREAD; - dynID=node.getTempDescriptor().toString(); - } else { - // fine-grain write - type = FINEWRITE; - dynID=node.getTempDescriptor().toString(); - } - } - - if (type > -1) { - for (Iterator seseLockIter = seseLockSet + for (Iterator seseLockIter = seseLockSet .iterator(); seseLockIter.hasNext();) { SESELock seseLock = seseLockIter.next(); - if (seseLock.containsConflictNode(liveInNode)) { + if (seseLock.containsConflictNode(liveInNode) && seseLock.containsConflictEdge(conflictEdge)) { WaitingElement newElement = new WaitingElement(); - newElement.setAllocList(allocSet); newElement.setWaitingID(seseLock.getID()); - newElement.setStatus(type); - newElement.setDynID(dynID); - newElement.setConnectedSet(connectedSet); -// System.out.println(seseID+"connectedSet="+connectedSet); + newElement.setStatus(seseLock.getNodeType(liveInNode)); + if(isFineElement(newElement.getStatus())){ + newElement.setDynID(node.getTempDescriptor().toString()); + } if(!waitingElementSet.contains(newElement)){ waitingElementSet.add(newElement); - }else{ - for (Iterator iterator2 = waitingElementSet - .iterator(); iterator2 - .hasNext();) { - WaitingElement e = (WaitingElement) iterator2 - .next(); - if(e.equals(newElement)){ - e.getConnectedSet().addAll(connectedSet); -// System.out.println(seseID+"!!!connectedSet="+e.getConnectedSet()); - } - } - - } - - } } } } @@ -1024,6 +936,16 @@ public class ConflictGraph { return waitingElementSet; } + + public boolean isFineElement(int type) { + if (type == ConflictNode.FINE_READ || type == ConflictNode.FINE_WRITE + || type == ConflictNode.PARENT_READ + || type == ConflictNode.PARENT_WRITE) { + return true; + } else { + return false; + } + } public Set getAllocationSiteIDSetBySESEID(int seseID) { // deprecated diff --git a/Robust/src/Analysis/MLP/ConflictNode.java b/Robust/src/Analysis/MLP/ConflictNode.java index 2ea41c02..8243ad88 100644 --- a/Robust/src/Analysis/MLP/ConflictNode.java +++ b/Robust/src/Analysis/MLP/ConflictNode.java @@ -19,8 +19,9 @@ public abstract class ConflictNode { public static final int PARENT_READ = 2; public static final int PARENT_WRITE = 3; public static final int COARSE = 4; - public static final int SCC = 5; - public static final int PARENT_COARSE = 6; + public static final int PARENT_COARSE = 5; + public static final int SCC = 6; + public ConflictNode() { diff --git a/Robust/src/Analysis/MLP/MLPAnalysis.java b/Robust/src/Analysis/MLP/MLPAnalysis.java index b1765e66..2533d5a2 100644 --- a/Robust/src/Analysis/MLP/MLPAnalysis.java +++ b/Robust/src/Analysis/MLP/MLPAnalysis.java @@ -110,6 +110,7 @@ public class MLPAnalysis { private Hashtable isAfterChildSESEIndicatorMap; private Hashtable seseSummaryMap; private Hashtable> conflictGraphLockMap; + static private int uniqueLockSetId = 0; public static int maxSESEage = -1; @@ -336,7 +337,6 @@ public class MLPAnalysis { System.exit(0); } } - } @@ -2071,6 +2071,7 @@ public class MLPAnalysis { while (!toCover.isEmpty()) { SESELock seseLock = new SESELock(); + seseLock.setID(uniqueLockSetId++); boolean changed; @@ -2081,46 +2082,48 @@ public class MLPAnalysis { for (Iterator iterator = fineToCover.iterator(); iterator .hasNext();) { + int type; ConflictEdge edge = (ConflictEdge) iterator.next(); if(seseLock.getConflictNodeSet().size()==0){ //initial setup - if(seseLock.hasSelfEdge(edge.getVertexU())){ + if(seseLock.isWriteNode(edge.getVertexU())){ // mark as fine_write if(edge.getVertexU() instanceof StallSiteNode){ - edge.getVertexU().setType(ConflictNode.PARENT_WRITE); + type=ConflictNode.PARENT_WRITE; }else{ - edge.getVertexU().setType(ConflictNode.FINE_WRITE); + type=ConflictNode.FINE_WRITE; } - seseLock.getConflictNodeSet().add(edge.getVertexU()); + seseLock.addConflictNode(edge.getVertexU(), type); }else{ // mark as fine_read if(edge.getVertexU() instanceof StallSiteNode){ - edge.getVertexU().setType(ConflictNode.PARENT_READ); + type=ConflictNode.PARENT_READ; }else{ - edge.getVertexU().setType(ConflictNode.FINE_READ); + type=ConflictNode.FINE_READ; } - seseLock.getConflictNodeSet().add(edge.getVertexU()); + seseLock.addConflictNode(edge.getVertexU(), type); } if(edge.getVertexV()!=edge.getVertexU()){ - if(seseLock.hasSelfEdge(edge.getVertexV())){ + if(seseLock.isWriteNode(edge.getVertexV())){ // mark as fine_write if(edge.getVertexV() instanceof StallSiteNode){ - edge.getVertexV().setType(ConflictNode.PARENT_WRITE); + type=ConflictNode.PARENT_WRITE; }else{ - edge.getVertexV().setType(ConflictNode.FINE_WRITE); + type=ConflictNode.FINE_WRITE; } - seseLock.getConflictNodeSet().add(edge.getVertexV()); + seseLock.addConflictNode(edge.getVertexV(), type); }else{ // mark as fine_read if(edge.getVertexV() instanceof StallSiteNode){ - edge.getVertexV().setType(ConflictNode.PARENT_WRITE); + type=ConflictNode.PARENT_READ; }else{ - edge.getVertexV().setType(ConflictNode.FINE_READ); + type=ConflictNode.FINE_READ; } - seseLock.getConflictNodeSet().add(edge.getVertexV()); + seseLock.addConflictNode(edge.getVertexV(), type); } } changed=true; + seseLock.addConflictEdge(edge); fineToCover.remove(edge); break;// exit iterator loop }// end of initial setup @@ -2133,18 +2136,20 @@ public class MLPAnalysis { changed=true; - if(seseLock.hasSelfEdge(newNode)){ + if(seseLock.isWriteNode(newNode)){ if(newNode instanceof StallSiteNode){ - newNode.setType(ConflictNode.PARENT_WRITE); + type=ConflictNode.PARENT_WRITE; }else{ - newNode.setType(ConflictNode.FINE_WRITE); + type=ConflictNode.FINE_WRITE; } + seseLock.setNodeType(newNode,type); }else{ if(newNode instanceof StallSiteNode){ - newNode.setType(ConflictNode.PARENT_READ); + type=ConflictNode.PARENT_READ; }else{ - newNode.setType(ConflictNode.FINE_READ); + type=ConflictNode.FINE_READ; } + seseLock.setNodeType(newNode,type); } seseLock.addEdge(edge); @@ -2159,11 +2164,13 @@ public class MLPAnalysis { if(!conflictEdge.getVertexU().equals(newNode)){ if(seseLock.containsConflictNode(conflictEdge.getVertexU())){ changed=true; + seseLock.addConflictEdge(conflictEdge); fineToCover.remove(conflictEdge); } }else if(!conflictEdge.getVertexV().equals(newNode)){ if(seseLock.containsConflictNode(conflictEdge.getVertexV())){ changed=true; + seseLock.addConflictEdge(conflictEdge); fineToCover.remove(conflictEdge); } } @@ -2175,11 +2182,9 @@ public class MLPAnalysis { } }while(changed); - do{ // coarse - changed=false; - + int type; for (Iterator iterator = coarseToCover.iterator(); iterator .hasNext();) { @@ -2187,41 +2192,43 @@ public class MLPAnalysis { if(seseLock.getConflictNodeSet().size()==0){ //initial setup - if(seseLock.hasSelfEdge(edge.getVertexU())){ + if(seseLock.hasSelfCoarseEdge(edge.getVertexU())){ // node has a coarse-grained edge with itself if(!(edge.getVertexU() instanceof StallSiteNode)){ // and it is not parent - edge.getVertexU().setType(ConflictNode.SCC); + type=ConflictNode.SCC; }else{ - edge.getVertexU().setType(ConflictNode.PARENT_COARSE); + type=ConflictNode.PARENT_COARSE; } - seseLock.getConflictNodeSet().add(edge.getVertexU()); + seseLock.addConflictNode(edge.getVertexU(), type); }else{ if(edge.getVertexU() instanceof StallSiteNode){ - edge.getVertexU().setType(ConflictNode.PARENT_COARSE); + type=ConflictNode.PARENT_COARSE; }else{ - edge.getVertexU().setType(ConflictNode.COARSE); + type=ConflictNode.COARSE; } - seseLock.getConflictNodeSet().add(edge.getVertexU()); + seseLock.addConflictNode(edge.getVertexU(), type); } - if(seseLock.hasSelfEdge(edge.getVertexV())){ + if(seseLock.hasSelfCoarseEdge(edge.getVertexV())){ // node has a coarse-grained edge with itself if(!(edge.getVertexV() instanceof StallSiteNode)){ // and it is not parent - edge.getVertexV().setType(ConflictNode.SCC); + type=ConflictNode.SCC; }else{ - edge.getVertexV().setType(ConflictNode.PARENT_COARSE); + type=ConflictNode.PARENT_COARSE; } - seseLock.getConflictNodeSet().add(edge.getVertexV()); + seseLock.addConflictNode(edge.getVertexV(), type); }else{ if(edge.getVertexV() instanceof StallSiteNode){ - edge.getVertexV().setType(ConflictNode.PARENT_COARSE); + type=ConflictNode.PARENT_COARSE; }else{ - edge.getVertexV().setType(ConflictNode.COARSE); + type=ConflictNode.COARSE; } - seseLock.getConflictNodeSet().add(edge.getVertexV()); + seseLock.addConflictNode(edge.getVertexV(), type); } changed=true; + coarseToCover.remove(edge); + seseLock.addConflictEdge(edge); break;// exit iterator loop }// end of initial setup @@ -2229,21 +2236,23 @@ public class MLPAnalysis { ConflictNode newNode; if((newNode=seseLock.getNewNodeConnectedWithGroup(edge))!=null){ // new node has a coarse-grained edge to all fine-read, fine-write, parent - changed=true; + changed=true; - if(seseLock.hasSelfEdge(newNode)){ + if(seseLock.hasSelfCoarseEdge(newNode)){ //SCC if(newNode instanceof StallSiteNode){ - newNode.setType(ConflictNode.PARENT_COARSE); + type=ConflictNode.PARENT_COARSE; }else{ - newNode.setType(ConflictNode.SCC); + type=ConflictNode.SCC; } + seseLock.setNodeType(newNode, type); }else{ if(newNode instanceof StallSiteNode){ - newNode.setType(ConflictNode.PARENT_COARSE); + type=ConflictNode.PARENT_COARSE; }else{ - newNode.setType(ConflictNode.COARSE); + type=ConflictNode.COARSE; } + seseLock.setNodeType(newNode, type); } seseLock.addEdge(edge); @@ -2256,11 +2265,13 @@ public class MLPAnalysis { if(!conflictEdge.getVertexU().equals(newNode)){ if(seseLock.containsConflictNode(conflictEdge.getVertexU())){ changed=true; + seseLock.addConflictEdge(conflictEdge); coarseToCover.remove(conflictEdge); } }else if(!conflictEdge.getVertexV().equals(newNode)){ if(seseLock.containsConflictNode(conflictEdge.getVertexV())){ changed=true; + seseLock.addConflictEdge(conflictEdge); coarseToCover.remove(conflictEdge); } } @@ -2269,12 +2280,9 @@ public class MLPAnalysis { break;// exit iterator loop } - } }while(changed); - -// System.out.println("lock="+seseLock); lockSet.add(seseLock); toCover.clear(); diff --git a/Robust/src/Analysis/MLP/SESELock.java b/Robust/src/Analysis/MLP/SESELock.java index d4c4e5e4..e8119066 100644 --- a/Robust/src/Analysis/MLP/SESELock.java +++ b/Robust/src/Analysis/MLP/SESELock.java @@ -1,27 +1,79 @@ package Analysis.MLP; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Set; public class SESELock { private HashSet conflictNodeSet; + private HashSet conflictEdgeSet; + private HashMap nodeTypeMap; private int id; public SESELock(){ conflictNodeSet=new HashSet(); + conflictEdgeSet=new HashSet(); + nodeTypeMap=new HashMap(); + } + + public void addConflictNode(ConflictNode node, int type){ + conflictNodeSet.add(node); + setNodeType(node, type); + } + + public void setNodeType(ConflictNode node, int type){ + nodeTypeMap.put(node, new Integer(type)); + } + + public int getNodeType(ConflictNode node){ + return nodeTypeMap.get(node).intValue(); + } + + public void addConflictEdge(ConflictEdge e){ + conflictEdgeSet.add(e); + } + + public boolean containsConflictEdge(ConflictEdge e){ + return conflictEdgeSet.contains(e); } public HashSet getConflictNodeSet(){ return conflictNodeSet; } - public boolean hasSelfEdge(ConflictNode node){ + public boolean isWriteNode(ConflictNode node){ + if (node instanceof StallSiteNode) { + StallSiteNode stallSiteNode = (StallSiteNode) node; + HashSet effectSet = stallSiteNode.getStallSite() + .getEffectSet(); + for (Iterator iterator = effectSet.iterator(); iterator.hasNext();) { + Effect effect = (Effect) iterator.next(); + if (effect.getEffectType().equals(StallSite.WRITE_EFFECT)) { + return true; + } + } + } else { + LiveInNode liveInNode = (LiveInNode) node; + Set writeEffectSet = liveInNode + .getWriteEffectsSet(); + if (writeEffectSet != null && writeEffectSet.size() > 0) { + return true; + } + } + + return false; + + } + + + public boolean hasSelfCoarseEdge(ConflictNode node){ HashSet set=node.getEdgeSet(); for (Iterator iterator = set.iterator(); iterator.hasNext();) { ConflictEdge conflictEdge = (ConflictEdge) iterator.next(); - if(conflictEdge.getVertexU()==conflictEdge.getVertexV()){ + if(conflictEdge.getType()!=ConflictEdge.FINE_GRAIN_EDGE&&conflictEdge.getVertexU()==conflictEdge.getVertexV()){ return true; } } @@ -160,7 +212,7 @@ public class SESELock { for (Iterator iterator = conflictNodeSet.iterator(); iterator.hasNext();) { ConflictNode node = (ConflictNode) iterator.next(); - rtr+=" "+node; + rtr+=" "+node+"::"+getNodeType(node); } return rtr; diff --git a/Robust/src/Analysis/MLP/WaitingElement.java b/Robust/src/Analysis/MLP/WaitingElement.java index 76e07e0f..97927046 100644 --- a/Robust/src/Analysis/MLP/WaitingElement.java +++ b/Robust/src/Analysis/MLP/WaitingElement.java @@ -7,27 +7,12 @@ public class WaitingElement { private int waitingID; private int status; - private HashSet allocList; - private String dynID; - private HashSet connectedSet; + private String dynID=""; - public WaitingElement() { - this.allocList = new HashSet(); - this.connectedSet = new HashSet(); - } - public void setWaitingID(int waitingID) { this.waitingID = waitingID; } - public HashSet getConnectedSet() { - return connectedSet; - } - - public void setConnectedSet(HashSet connectedSet) { - this.connectedSet.addAll(connectedSet); - } - public String getDynID(){ return dynID; } @@ -48,14 +33,6 @@ public class WaitingElement { return status; } - public HashSet getAllocList() { - return allocList; - } - - public void setAllocList(HashSet allocList) { - this.allocList.addAll(allocList); - } - public boolean equals(Object o) { if (o == null) { @@ -68,8 +45,7 @@ public class WaitingElement { WaitingElement in = (WaitingElement) o; - if (waitingID == in.getQueueID() && status == in.getStatus() - && allocList.equals(in.getAllocList())) { + if (waitingID == in.getQueueID() && status == in.getStatus() && dynID.equals(in.getDynID()) ) { return true; } else { return false; @@ -78,8 +54,8 @@ public class WaitingElement { } public String toString() { - return "[waitingID=" + waitingID + " status=" + status + " allocList=" - + allocList + "]"; + return "[waitingID=" + waitingID + " status=" + status + " dynID=" + + dynID + "]"; } public int hashCode() { @@ -89,11 +65,8 @@ public class WaitingElement { hash = hash * 31 + waitingID; hash += status; - - for (Iterator iterator = allocList.iterator(); iterator.hasNext();) { - Integer type = (Integer) iterator.next(); - hash += type.intValue(); - } + + hash += dynID.hashCode(); return hash; diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index d47d5c79..2d4231e6 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -28,6 +28,7 @@ import Analysis.Loops.WriteBarrier; import Analysis.Loops.GlobalFieldType; import Analysis.Locality.TypeAnalysis; import Analysis.MLP.ConflictGraph; +import Analysis.MLP.ConflictNode; import Analysis.MLP.MLPAnalysis; import Analysis.MLP.ParentChildConflictsMap; import Analysis.MLP.SESELock; @@ -1772,15 +1773,21 @@ public class BuildCode { // set up related allocation sites's waiting queues // eom - output.println(" /* set up waiting queues */"); - output.println(" int numMemoryQueue=0;"); - output.println(" int memoryQueueItemID=0;"); ConflictGraph graph = null; graph = mlpa.getConflictGraphResults().get(fm); if (graph != null) { + output.println(" /* set up waiting queues */"); + output.println(" int numMemoryQueue=0;"); + output.println(" int memoryQueueItemID=0;"); HashSet lockSet = mlpa.getConflictGraphLockMap().get( graph); - + System.out.println("lockset="+lockSet); + for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) { + SESELock seseLock = (SESELock) iterator.next(); + System.out.println("id="+seseLock.getID()); + System.out.println("#="+seseLock); + } + System.out.println("size="+lockSet.size()); if (lockSet.size() > 0) { output.println(" numMemoryQueue=" + lockSet.size() + ";"); output @@ -2724,21 +2731,23 @@ public class BuildCode { output.println("// stall on parent's stall sites "); output.println(" {"); output.println(" REntry* rentry;"); - output.println(" pthread_mutex_lock( &(seseCaller->lock) );"); for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { WaitingElement waitingElement = (WaitingElement) iterator.next(); - output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseCaller, ___locals___."+ waitingElement.getDynID() + ");"); - output.println(" pthread_cond_init( &(rentry->stallDone), NULL );"); + if( waitingElement.getStatus() >= ConflictNode.COARSE ){ + output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseCaller);"); + }else{ + output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseCaller, ___locals___."+ waitingElement.getDynID() + ");"); + } + output.println(" psem_init( &(rentry->parentStallSem) );"); output.println(" rentry->queue=seseCaller->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); output .println(" if(ADDRENTRY(seseCaller->memoryQueueArray["+ waitingElement.getQueueID() + "],rentry)==NOTREADY){"); - output.println(" pthread_cond_wait( &(rentry->stallDone), &(seseCaller->lock) );"); + output.println(" psem_take( &(rentry->parentStallSem) );"); output.println(" } "); } - output.println(" pthread_mutex_unlock( &(seseCaller->lock) );"); output.println(" }"); } } @@ -3369,13 +3378,16 @@ public class BuildCode { output.println(" {"); output.println(" REntry* rentry=NULL;"); output.println(" seseToIssue->common.rentryIdx=0;"); - output - .println(" pthread_mutex_lock( &(parentCommon->lock) );"); for (Iterator iterator = waitingQueueSet.iterator(); iterator .hasNext();) { WaitingElement waitingElement = (WaitingElement) iterator .next(); - output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseToIssue, seseToIssue->"+ waitingElement.getDynID() + ");"); + + if( waitingElement.getStatus() >= ConflictNode.COARSE ){ + output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseToIssue);"); + }else{ + output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseToIssue, seseToIssue->"+ waitingElement.getDynID() + ");"); + } output.println(" rentry->queue=parentCommon->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); output @@ -3386,8 +3398,6 @@ public class BuildCode { output.println(" } "); output.println(); } - output - .println(" pthread_mutex_unlock( &(parentCommon->lock) );"); output.println(" }"); } output.println(); @@ -3602,15 +3612,11 @@ public class BuildCode { output.println(); output.println(" /* check memory dependency*/"); output.println(" {"); - output - .println(" pthread_mutex_lock( &(___params___->common.parent->lock) );"); output.println(" int idx;"); output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){"); output.println(" REntry* re=___params___->common.rentryArray[idx];"); output.println(" RETIRERENTRY(re->queue,re);"); output.println(" }"); - output - .println(" pthread_mutex_unlock( &(___params___->common.parent->lock) );"); output.println(" }"); } diff --git a/Robust/src/Runtime/mlp_lock.h b/Robust/src/Runtime/mlp_lock.h index 6086ffc4..9ce327c4 100644 --- a/Robust/src/Runtime/mlp_lock.h +++ b/Robust/src/Runtime/mlp_lock.h @@ -4,6 +4,7 @@ #include #include +#define __xg(x) ((volatile long *)(x)) #define CFENCE asm volatile("":::"memory"); @@ -66,6 +67,24 @@ static inline int CAS(volatile int* mem, int cmp, int val){ return prev; } +static inline long CAS32(volatile void *ptr, unsigned long old, unsigned long new){ + unsigned long prev; + __asm__ __volatile__("lock; cmpxchgl %k1,%2" + : "=a"(prev) + : "r"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; +} + +static inline long long CAS64(volatile void *ptr, unsigned long long old, unsigned long long new){ + unsigned long long prev; + __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2" + : "=a"(prev) + : "r"(new), "m"(*__xg(ptr)), "0"(old) + : "memory"); + return prev; +} + static inline int BARRIER(){ CFENCE; return 1; diff --git a/Robust/src/Runtime/mlp_runtime.c b/Robust/src/Runtime/mlp_runtime.c index 69581bf3..e0ab2b50 100644 --- a/Robust/src/Runtime/mlp_runtime.c +++ b/Robust/src/Runtime/mlp_runtime.c @@ -47,7 +47,7 @@ REntry* mlpCreateREntryArray(){ return newREntryArray; } -REntry* mlpCreateREntry(int type, void* seseToIssue, void* dynID){ +REntry* mlpCreateFineREntry(int type, void* seseToIssue, void* dynID){ REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry)); newREntry->type=type; newREntry->seseRec=seseToIssue; @@ -55,6 +55,13 @@ REntry* mlpCreateREntry(int type, void* seseToIssue, void* dynID){ return newREntry; } +REntry* mlpCreateREntry(int type, void* seseToIssue){ + REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry)); + newREntry->type=type; + newREntry->seseRec=seseToIssue; + return newREntry; +} + int isParent(REntry *r) { if (r->type==PARENTREAD || r->type==PARENTWRITE) { return TRUE; @@ -150,7 +157,7 @@ int generateKey(unsigned int data){ Hashtable* createHashtable(){ int i=0; Hashtable* newTable=(Hashtable*)RUNMALLOC(sizeof(Hashtable)); - //newTable->array=(BinElement*)RUNMALLOC(sizeof(BinElement)*NUMBINS); + newTable->item.type=HASHTABLE; for(i=0;iarray[i]=(BinElement*)RUNMALLOC(sizeof(BinElement)); newTable->array[i]->head=NULL; @@ -167,7 +174,6 @@ WriteBinItem* createWriteBinItem(){ ReadBinItem* createReadBinItem(){ ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem)); - binitem->array=(REntry*)RUNMALLOC(sizeof(REntry*)*NUMREAD); binitem->index=0; binitem->item.type=READBIN; return binitem; @@ -175,21 +181,21 @@ ReadBinItem* createReadBinItem(){ Vector* createVector(){ Vector* vector=(Vector*)RUNMALLOC(sizeof(Vector)); - vector->array=(REntry*)RUNMALLOC(sizeof(REntry*)*NUMITEMS); vector->index=0; + vector->item.type=VECTOR; return vector; } SCC* createSCC(){ SCC* scc=(SCC*)RUNMALLOC(sizeof(SCC)); + scc->item.type=SINGLEITEM; return scc; } MemoryQueue* createMemoryQueue(){ MemoryQueue* queue = (MemoryQueue*)RUNMALLOC(sizeof(MemoryQueue)); - MemoryQueueItem* dummy=(MemoryQueueItem*)RUNMALLOC(sizeof(MemoryQueueItem)); - dummy->type=3; + dummy->type=3; // dummy type dummy->total=0; dummy->status=READY; queue->head = dummy; @@ -224,6 +230,10 @@ int ADDTABLE(MemoryQueue *q, REntry *r) { h->item.status=READY; } q->tail=(MemoryQueueItem*)h; + // handle the the queue item case + if(q->head->type==3){ + q->head=(MemoryQueueItem*)h; + } } //at this point, have table @@ -240,10 +250,9 @@ int ADDTABLE(MemoryQueue *q, REntry *r) { return EMPTYBINCASE(table, table->array[key], r); } else { if (isFineWrite(r)) { - WRITEBINCASE(table, r, val); - return NOTREADY; + return WRITEBINCASE(table, r, val, key); } else if (isFineRead(r)) { - return READBINCASE(table, r, val); + return READBINCASE(table, r, val, key); } } } @@ -257,7 +266,7 @@ int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r) { } else if (isFineRead(r)) { b=(BinItem*)createReadBinItem(); ReadBinItem* readbin=(ReadBinItem*)b; - readbin->array[readbin->index++]=*r; + readbin->array[readbin->index++]=r; } b->total=1; @@ -282,17 +291,27 @@ int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r) { return retval; } -int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val) { +int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) { //chain of bins exists => tail is valid //if there is something in front of us, then we are not ready - int key=generateKey((unsigned int)r->dynID); + int retval; BinElement* be=T->array[key]; BinItem *bintail=be->tail; + WriteBinItem *b=createWriteBinItem(); b->val=r; b->item.total=1; + + // note: If current table clears all dependencies, then write bin is ready + if (T->item.total==0){ + retval=READY; + }else{ + retval=NOTREADY; + } + b->item.status=retval; + // b->item.status=NOTREADY; atomic_inc(&T->item.total); @@ -302,21 +321,20 @@ int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val) { be->tail->next=(BinItem*)b; be->tail=(BinItem*)b; be->head=val; + return retval; } -READBINCASE(Hashtable *T, REntry *r, BinItem *val) { - int key=generateKey((unsigned int)r->dynID); +READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) { BinItem * bintail=T->array[key]->tail; if (isReadBinItem(bintail)) { - return TAILREADCASE(T, r, val, bintail); + return TAILREADCASE(T, r, val, bintail, key); } else if (!isReadBinItem(bintail)) { - TAILWRITECASE(T, r, val, bintail); + TAILWRITECASE(T, r, val, bintail, key); return NOTREADY; } } -int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail) { - int key=generateKey((unsigned int)r->dynID); +int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key) { ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail; int status, retval; if (readbintail->item.status=READY) { @@ -333,16 +351,17 @@ int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail) { if (readbintail->index==NUMREAD) { // create new read group ReadBinItem* rb=createReadBinItem(); - rb->array[rb->index++]=*r; + rb->array[rb->index++]=r; rb->item.total=1;//safe only because item could not have started rb->item.status=status; T->array[key]->tail->next=(BinItem*)rb; T->array[key]->tail=(BinItem*)rb; r->binitem=(BinItem*)rb; } else { // group into old tail - readbintail->array[readbintail->index++]=*r; + readbintail->array[readbintail->index++]=r; atomic_inc(&readbintail->item.total); r->binitem=(BinItem*)readbintail; + //printf("grouping with %d\n",readbintail->index); } atomic_inc(&T->item.total); r->hashtable=T; @@ -350,20 +369,20 @@ int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail) { return retval; } -TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail) { - int key=generateKey((unsigned int)r->dynID); - WriteBinItem* wb=createWriteBinItem(); - wb->val=r; - wb->item.total=1; - wb->item.status=NOTREADY; - // rb->array[rb->index++]=*r; - //rb->item.total=1;//safe because item could not have started - //rb->item.status=NOTREADY; +TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key) { + // WriteBinItem* wb=createWriteBinItem(); + //wb->val=r; + //wb->item.total=1;//safe because item could not have started + //wb->item.status=NOTREADY; + ReadBinItem* rb=createReadBinItem(); + rb->array[rb->index++]=r; + rb->item.total=1;//safe because item could not have started + rb->item.status=NOTREADY; atomic_inc(&T->item.total); r->hashtable=T; - r->binitem=(BinItem*)wb; - T->array[key]->tail->next=(BinItem*)wb; - T->array[key]->tail=(BinItem*)wb; + r->binitem=(BinItem*)rb; + T->array[key]->tail->next=(BinItem*)rb; + T->array[key]->tail=(BinItem*)rb; T->array[key]->head=val;//released lock } @@ -383,6 +402,10 @@ ADDVECTOR(MemoryQueue *Q, REntry *r) { V->item.status=READY; } Q->tail=(MemoryQueueItem*)V; + // handle the the queue item case + if(Q->head->type==3){ + Q->head=(MemoryQueueItem*)V; + } } //at this point, have vector Vector* V=(Vector*)Q->tail; @@ -402,14 +425,15 @@ ADDVECTOR(MemoryQueue *Q, REntry *r) { atomic_inc(&V->item.total); //expose entry int index=V->index; - V->array[index]=*r; + V->array[index]=r; //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index BARRIER(); V->index++; //*****NEED memory barrier here to ensure compiler does not cache V.status********* + r->vector=V; if (BARRIER() && V->item.status==READY) { void* flag=NULL; - LOCKXCHG((unsigned int*)&(V->array[index]), (unsigned int)flag); + flag=(void*)LOCKXCHG((unsigned int*)&(V->array[index]), (unsigned int)flag); if (flag!=NULL) { if (isParent(r)) { //parent's retire immediately atomic_dec(&V->item.total); @@ -430,14 +454,19 @@ ADDSCC(MemoryQueue *Q, REntry *r) { SCC* S=createSCC(); S->item.total=1; S->val=r; + r->scc=S; Q->tail->next=(MemoryQueueItem*)S; //*** NEED BARRIER HERE if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) { //previous Q item is finished S->item.status=READY; Q->tail=(MemoryQueueItem*)S; + // handle the the queue item case + if(Q->head->type==3){ + Q->head=(MemoryQueueItem*)S; + } void* flag=NULL; - LOCKXCHG((int*)S->val, (int)flag); + flag=(void*)LOCKXCHG((unsigned int*)&(S->val), (unsigned int)flag); if (flag!=NULL) { return READY; } else { @@ -483,7 +512,7 @@ RETIREBIN(Hashtable *T, REntry *r, BinItem *b) { atomic_dec(&b->total); } if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) { - // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change + // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change BinItem * val; do { val=(BinItem*)1; @@ -500,8 +529,7 @@ RETIREBIN(Hashtable *T, REntry *r, BinItem *b) { if (rptr->item.status==NOTREADY) { for (i=0;iindex;i++) { resolveDependencies(rptr->array[i]); - // XXXXX atomicdec(rptr->array[i].dependenciesCount); - if (isParent(&rptr->array[i])) { + if (isParent(rptr->array[i])) { //parents go immediately atomic_dec(&rptr->item.total); atomic_dec(&T->item.total); @@ -532,9 +560,10 @@ RETIREBIN(Hashtable *T, REntry *r, BinItem *b) { val=val->next; } /* - if(ptr->status==NOTREADY) { - ptr->status=READY; + if(ptr->status==NOTREADY) { resolveDependencies(((WriteBinItem*)ptr)->val); + } + ptr->status=READY; if (isParent(((WriteBinItem*)ptr)->val)) { atomic_dec(&T->item.total); //val=val->next; @@ -554,7 +583,6 @@ RETIREBIN(Hashtable *T, REntry *r, BinItem *b) { RETIREVECTOR(MemoryQueue *Q, REntry *r) { Vector* V=r->vector; atomic_dec(&V->item.total); - if (V->item.next!=NULL && V->item.total==0) { //NOTE: ORDERING CRUCIAL HERE RESOLVECHAIN(Q); } @@ -583,7 +611,7 @@ RESOLVECHAIN(MemoryQueue *Q) { break; } MemoryQueueItem* nextitem=head->next; - CAS((int*)Q->head, (int)head, (int)nextitem); + CAS32((unsigned int*)&(Q->head), (unsigned int)head, (unsigned int)nextitem); //oldvalue not needed... if we fail we just repeat } } @@ -596,7 +624,7 @@ RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) { BinItem* val; do { val=(BinItem*)1; - LOCKXCHG((int*)bin->head, (int)val); + val=(BinItem*)LOCKXCHG((unsigned int*)&(bin->head), (unsigned int)val); } while (val==(BinItem*)1); //at this point have locked bin int haveread=FALSE; @@ -607,8 +635,7 @@ RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) { if (haveread) break; resolveDependencies(((WriteBinItem*)ptr)->val); - // XXXXX atomic_dec(ptr.val.dependenciesCount); - ptr->status=READY; + ptr->status=READY; if (isParent(((WriteBinItem*)ptr)->val)) { atomic_dec(&T->item.total); val=val->next; @@ -619,8 +646,7 @@ RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) { ReadBinItem* rptr=(ReadBinItem*)ptr; for(i=0;iindex;i++) { resolveDependencies(rptr->array[i]); - // XXXXX atomicdec(ptr.array[i].dependenciesCount); - if (isParent(&rptr->array[i])) { + if (isParent(rptr->array[i])) { atomic_dec(&rptr->item.total); atomic_dec(&T->item.total); } @@ -647,11 +673,11 @@ RESOLVEVECTOR(MemoryQueue *q, Vector *V) { while(TRUE) { //enqueue everything for (i=0;iarray[i], (int)val); + REntry* val=NULL; + val=(REntry*)LOCKXCHG((unsigned int*)&(tmp->array[i]), (unsigned int)val); if (val!=NULL) { - // XXXXX atomicdec(val.dependenciesCount); - if (isParent(val)) { + resolveDependencies(val); + if (isParent(val)) { atomic_dec(&tmp->item.total); } } @@ -667,20 +693,20 @@ RESOLVEVECTOR(MemoryQueue *q, Vector *V) { RESOLVESCC(SCC *S) { //precondition: SCC's state is READY void* flag=NULL; - LOCKXCHG((int*)S->val, (int)flag); + flag=(void*)LOCKXCHG((unsigned int*)&(S->val), (unsigned int)flag); if (flag!=NULL) { - // XXXXX atomicdec(flag.dependenciesCount); + resolveDependencies(flag); } } resolveDependencies(REntry* rentry){ SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec; - if(rentry->type==0 || rentry->type==1){ + if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){ if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){ workScheduleSubmit(seseCommon); } - }else if(rentry->type==2 || rentry->type==3){ - pthread_cond_signal(&(rentry->stallDone)); + }else if(rentry->type==PARENTREAD || rentry->type==PARENTWRITE ||rentry->type==PARENTCOARSE){ + psem_give(&(rentry->parentStallSem)); } } diff --git a/Robust/src/Runtime/mlp_runtime.h b/Robust/src/Runtime/mlp_runtime.h index 7087408d..abf5b747 100644 --- a/Robust/src/Runtime/mlp_runtime.h +++ b/Robust/src/Runtime/mlp_runtime.h @@ -55,7 +55,7 @@ typedef struct REntry_t{ struct Vector_t* vector; struct SCC_t* scc; struct MemoryQueue_t* queue; - pthread_cond_t stallDone; + psemaphore parentStallSem; void* seseRec; void* dynID; } REntry; @@ -96,13 +96,13 @@ typedef struct WriteBinItem_t { typedef struct ReadBinItem_t { BinItem item; - REntry * array; + REntry * array[NUMREAD]; int index; } ReadBinItem; typedef struct Vector_t { MemoryQueueItem item; - REntry * array; + REntry * array[NUMITEMS]; int index; } Vector; @@ -114,7 +114,6 @@ typedef struct SCC_t { int ADDRENTRY(MemoryQueue* q, REntry * r); void RETIRERENTRY(MemoryQueue* Q, REntry * r); -//////////////////////////////////////// // forward declaration of pointer type typedef struct SESEcommon_t* SESEcommon_p; @@ -149,7 +148,7 @@ typedef struct SESEcommon_t { SESEcommon_p parent; - psemaphore memoryStallSiteSem; + psemaphore parentStallSem; pthread_cond_t stallDone; int numMemoryQueue; @@ -159,14 +158,6 @@ typedef struct SESEcommon_t { } SESEcommon; -typedef struct WaitingElement_t{ - void* seseRec; - int status; - int id; - int resolved; - struct Queue* list; -} WaitingElement; - // a thread-local stack of SESEs and function to // ensure it is initialized once per thread /* @@ -184,11 +175,8 @@ void mlpDestroySESErecord( void* seseRecord ); void* mlpAllocSESErecord( int size ); MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue); -REntry* mlpCreateREntry(int type, void* seseToIssue, void* dynID); +REntry* mlpCreateFineREntry(int type, void* seseToIssue, void* dynID); +REntry* mlpCreateREntry(int type, void* seseToIssue); MemoryQueue* createMemoryQueue(); -////////////////////////////// - - - #endif /* __MLP_RUNTIME__ */