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<String, ConflictNode> id2cn;
private int determineWriteConflictsType(LiveInNode liveInNodeA,
LiveInNode liveInNodeB) {
+
+ if(liveInNodeA.getSESEIdentifier()==liveInNodeB.getSESEIdentifier()){
+ return ConflictEdge.NON_WRITE_CONFLICT;
+ }
Set<HeapRegionNode> liveInHrnSetA = liveInNodeA.getHRNSet();
Set<HeapRegionNode> liveInHrnSetB = liveInNodeB.getHRNSet();
} 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
addConflictEdge(conflictType, currentNode,
entryNode);
}
-
}
analyzedIDSet.add(currentNode.getID() + entryNodeID);
}
Set<Entry<String, ConflictNode>> s = id2cn.entrySet();
Collection<StallSite> stallSites = conflictsMap.getStallMap().values();
- String dynID="";
-
for (Iterator iterator = stallSites.iterator(); iterator.hasNext();) {
StallSite stallSite = (StallSite) iterator.next();
ConflictEdge conflictEdge = (ConflictEdge) iter2
.next();
- int type = -1;
- HashSet<Integer> allocSet = new HashSet<Integer>();
-
- 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<SESELock> 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);
}
}
- }
-
}
}
}
public Set<WaitingElement> getWaitingElementSetBySESEID(int seseID,
HashSet<SESELock> seseLockSet) {
-
HashSet<WaitingElement> waitingElementSet = new HashSet<WaitingElement>();
Set<Entry<String, ConflictNode>> s = id2cn.entrySet();
.hasNext();) {
ConflictEdge conflictEdge = (ConflictEdge) iterator
.next();
- int type = -1;
- HashSet<Integer> allocSet = new HashSet<Integer>();
- HashSet<Integer> connectedSet=new HashSet<Integer>();
- 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<SESELock> seseLockIter = seseLockSet
+ for (Iterator<SESELock> 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());
- }
- }
-
-
}
-
- }
}
}
}
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<Long> getAllocationSiteIDSetBySESEID(int seseID) {
// deprecated
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() {
private Hashtable<FlatNode, Boolean> isAfterChildSESEIndicatorMap;
private Hashtable<FlatNode, SESESummary> seseSummaryMap;
private Hashtable<ConflictGraph, HashSet<SESELock>> conflictGraphLockMap;
+ static private int uniqueLockSetId = 0;
public static int maxSESEage = -1;
System.exit(0);
}
}
-
}
while (!toCover.isEmpty()) {
SESELock seseLock = new SESELock();
+ seseLock.setID(uniqueLockSetId++);
boolean changed;
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
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);
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);
}
}
}
}while(changed);
-
do{ // coarse
-
changed=false;
-
+ int type;
for (Iterator iterator = coarseToCover.iterator(); iterator
.hasNext();) {
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
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);
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);
}
}
break;// exit iterator loop
}
-
}
}while(changed);
-
-// System.out.println("lock="+seseLock);
lockSet.add(seseLock);
toCover.clear();
package Analysis.MLP;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Set;
public class SESELock {
private HashSet<ConflictNode> conflictNodeSet;
+ private HashSet<ConflictEdge> conflictEdgeSet;
+ private HashMap<ConflictNode, Integer> nodeTypeMap;
private int id;
public SESELock(){
conflictNodeSet=new HashSet<ConflictNode>();
+ conflictEdgeSet=new HashSet<ConflictEdge>();
+ nodeTypeMap=new HashMap<ConflictNode, Integer>();
+ }
+
+ 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<ConflictNode> getConflictNodeSet(){
return conflictNodeSet;
}
- public boolean hasSelfEdge(ConflictNode node){
+ public boolean isWriteNode(ConflictNode node){
+ if (node instanceof StallSiteNode) {
+ StallSiteNode stallSiteNode = (StallSiteNode) node;
+ HashSet<Effect> 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<SESEEffectsKey> writeEffectSet = liveInNode
+ .getWriteEffectsSet();
+ if (writeEffectSet != null && writeEffectSet.size() > 0) {
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+
+ public boolean hasSelfCoarseEdge(ConflictNode node){
HashSet<ConflictEdge> 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;
}
}
for (Iterator<ConflictNode> iterator = conflictNodeSet.iterator(); iterator.hasNext();) {
ConflictNode node = (ConflictNode) iterator.next();
- rtr+=" "+node;
+ rtr+=" "+node+"::"+getNodeType(node);
}
return rtr;
private int waitingID;
private int status;
- private HashSet<Integer> allocList;
- private String dynID;
- private HashSet<Integer> connectedSet;
+ private String dynID="";
- public WaitingElement() {
- this.allocList = new HashSet<Integer>();
- this.connectedSet = new HashSet<Integer>();
- }
-
public void setWaitingID(int waitingID) {
this.waitingID = waitingID;
}
- public HashSet<Integer> getConnectedSet() {
- return connectedSet;
- }
-
- public void setConnectedSet(HashSet<Integer> connectedSet) {
- this.connectedSet.addAll(connectedSet);
- }
-
public String getDynID(){
return dynID;
}
return status;
}
- public HashSet<Integer> getAllocList() {
- return allocList;
- }
-
- public void setAllocList(HashSet<Integer> allocList) {
- this.allocList.addAll(allocList);
- }
-
public boolean equals(Object o) {
if (o == null) {
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;
}
public String toString() {
- return "[waitingID=" + waitingID + " status=" + status + " allocList="
- + allocList + "]";
+ return "[waitingID=" + waitingID + " status=" + status + " dynID="
+ + dynID + "]";
}
public int hashCode() {
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;
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;
// 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<SESELock> 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
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(" }");
}
}
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
output.println(" } ");
output.println();
}
- output
- .println(" pthread_mutex_unlock( &(parentCommon->lock) );");
output.println(" }");
}
output.println();
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(" }");
}
#include <stdio.h>
#include <assert.h>
+#define __xg(x) ((volatile long *)(x))
#define CFENCE asm volatile("":::"memory");
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;
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;
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;
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;i<NUMBINS;i++){
newTable->array[i]=(BinElement*)RUNMALLOC(sizeof(BinElement));
newTable->array[i]->head=NULL;
ReadBinItem* createReadBinItem(){
ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
- binitem->array=(REntry*)RUNMALLOC(sizeof(REntry*)*NUMREAD);
binitem->index=0;
binitem->item.type=READBIN;
return binitem;
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;
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
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);
}
}
}
} else if (isFineRead(r)) {
b=(BinItem*)createReadBinItem();
ReadBinItem* readbin=(ReadBinItem*)b;
- readbin->array[readbin->index++]=*r;
+ readbin->array[readbin->index++]=r;
}
b->total=1;
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);
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) {
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;
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
}
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;
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);
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 {
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;
if (rptr->item.status==NOTREADY) {
for (i=0;i<rptr->index;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);
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;
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);
}
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
}
}
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;
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;
ReadBinItem* rptr=(ReadBinItem*)ptr;
for(i=0;i<rptr->index;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);
}
while(TRUE) {
//enqueue everything
for (i=0;i<NUMITEMS;i++) {
- void* val=NULL;
- LOCKXCHG((int*)&tmp->array[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);
}
}
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));
}
}
struct Vector_t* vector;
struct SCC_t* scc;
struct MemoryQueue_t* queue;
- pthread_cond_t stallDone;
+ psemaphore parentStallSem;
void* seseRec;
void* dynID;
} REntry;
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;
int ADDRENTRY(MemoryQueue* q, REntry * r);
void RETIRERENTRY(MemoryQueue* Q, REntry * r);
-////////////////////////////////////////
// forward declaration of pointer type
typedef struct SESEcommon_t* SESEcommon_p;
SESEcommon_p parent;
- psemaphore memoryStallSiteSem;
+ psemaphore parentStallSem;
pthread_cond_t stallDone;
int numMemoryQueue;
} 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
/*
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__ */