for(Iterator<FlatNode> fnit=checkset.iterator();fnit.hasNext();) {
FlatNode fn=fnit.next();
//needs transread
- if (!state.READSET&&dc.getNeedTrans(lb, fn)||state.READSET&&dc.getNeedWriteTrans(lb, fn)) {
+ if (!state.READSET&&dc.getNeedTrans(lb, fn)||state.READSET&&dc.getNeedWriteTrans(lb, fn)||fn.kind()==FKind.FlatCall) {
System.out.println("False because"+fn);
if (!state.HYBRID)
return true;
}
}
+ public HashSet<FlatNode> computeWriteSet(LocalityBinding lb) {
+ HashSet<FlatNode> writeset=new HashSet<FlatNode>();
+ Set<FlatNode> storeset=livecode(lb);
+ HashSet<FlatNode> delayedset=getNotReady(lb);
+ Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> fnmap=dcopts.getMap(lb);
+ for(Iterator<FlatNode> fnit=delayedset.iterator();fnit.hasNext();) {
+ FlatNode fn=fnit.next();
+ Hashtable<TempDescriptor, Set<TempFlatPair>> tempmap=fnmap.get(fn);
+ if (fn.kind()==FKind.FlatSetElementNode) {
+ FlatSetElementNode fsen=(FlatSetElementNode) fn;
+ Set<TempFlatPair> tfpset=tempmap.get(fsen.getDst());
+ if (tfpset!=null) {
+ for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
+ TempFlatPair tfp=tfpit.next();
+ if (storeset.contains(tfp.f))
+ writeset.add(tfp.f);
+ }
+ }
+ } else if (fn.kind()==FKind.FlatSetFieldNode) {
+ FlatSetFieldNode fsfn=(FlatSetFieldNode) fn;
+ Set<TempFlatPair> tfpset=tempmap.get(fsfn.getDst());
+ if (tfpset!=null) {
+ for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
+ TempFlatPair tfp=tfpit.next();
+ if (storeset.contains(tfp.f))
+ writeset.add(tfp.f);
+ }
+ }
+ }
+ }
+ return writeset;
+ }
+
+
public HashSet<FlatNode> getNotReady(LocalityBinding lb) {
return notreadymap.get(lb);
}
Hashtable<LocalityBinding, Set<TempFlatPair>> transreadmap;
Hashtable<LocalityBinding, Set<FlatNode>> twritemap;
Hashtable<LocalityBinding, Set<TempFlatPair>> writemap;
+ Hashtable<LocalityBinding, Set<FlatNode>> getmap;
+
Hashtable<LocalityBinding, Set<FlatNode>> srcmap;
Hashtable<LocalityBinding, Set<FlatNode>> leftsrcmap;
Hashtable<LocalityBinding, Set<FlatNode>> rightsrcmap;
twritemap=new Hashtable<LocalityBinding, Set<FlatNode>>();
writemap=new Hashtable<LocalityBinding, Set<TempFlatPair>>();
}
+ getmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
this.gft=gft;
}
twritemap=new Hashtable<LocalityBinding, Set<FlatNode>>();
writemap=new Hashtable<LocalityBinding, Set<TempFlatPair>>();
}
+ getmap=new Hashtable<LocalityBinding, Set<FlatNode>>();
this.gft=gft;
}
for(Iterator<LocalityBinding> lb=localityset.iterator();lb.hasNext();) {
LocalityBinding l=lb.next();
analyzeLocality(l);
- setNeedReadTrans(l);
}
}
//Change flatnode/temp pairs to just flatnodes that need transactional reads
- public void setNeedReadTrans(LocalityBinding lb) {
+ private void setNeedReadTrans(LocalityBinding lb) {
HashSet<FlatNode> set=new HashSet<FlatNode>();
for(Iterator<TempFlatPair> it=transreadmap.get(lb).iterator();it.hasNext();) {
TempFlatPair tfp=it.next();
twritemap.put(lb, set);
}
}
+
+ private void computeneedsarrayget(LocalityBinding lb, Hashtable<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> fnmap) {
+ Set<FlatNode> writeset=(state.READSET&&gft!=null)?twritemap.get(lb):treadmap.get(lb);
+ FlatMethod fm=state.getMethodFlat(lb.getMethod());
+ HashSet<FlatNode> needsget=new HashSet<FlatNode>();
+ for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
+ FlatNode fn=fnit.next();
+ Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
+ if (atomictable.get(fn).intValue()>0&&fn.kind()==FKind.FlatElementNode) {
+ FlatElementNode fen=(FlatElementNode)fn;
+ Set<TempFlatPair> tfpset=fnmap.get(fen).get(fen.getSrc());
+ if (tfpset!=null) {
+ for(Iterator<TempFlatPair> tfpit=tfpset.iterator();tfpit.hasNext();) {
+ TempFlatPair tfp=tfpit.next();
+ if (writeset.contains(tfp.f)) {
+ needsget.add(tfp.f);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+ getmap.put(lb, needsget);
+ }
//We have a set of things we write to, figure out what things this
//could effect.
return treadmap.get(lb).contains(fn);
}
+ public boolean getNeedGet(LocalityBinding lb, FlatNode fn) {
+ if (gft!=null)
+ return getmap.get(lb).contains(fn);
+ else throw new Error();
+ }
+
public boolean getNeedWriteTrans(LocalityBinding lb, FlatNode fn) {
if (gft!=null)
return twritemap.get(lb).contains(fn);
if (atomictable.get(fn).intValue()>0) {
Hashtable<TempDescriptor, Set<TempFlatPair>> tmap=fnmap.get(fn);
switch(fn.kind()) {
-
//We might need to translate arguments to pointer comparison
case FKind.FlatOpNode: {
}
}
}
+ //Update results
+ setNeedReadTrans(lb);
+ computeneedsarrayget(lb, fnmap);
}
public boolean outofscope(TempFlatPair tfp) {
import Analysis.Locality.LocalityAnalysis;
import Analysis.Locality.LocalityBinding;
import Analysis.Locality.DiscoverConflicts;
+import Analysis.Locality.DCWrapper;
import Analysis.Locality.DelayComputation;
import Analysis.Locality.BranchAnalysis;
import Analysis.CallGraph.CallGraph;
WriteBarrier wb;
DiscoverConflicts dc;
DiscoverConflicts recorddc;
- DelayComputation delaycomp;
+ DCWrapper delaycomp;
CallGraph callgraph;
- boolean versionincrement;
public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
//TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain());
- delaycomp=new DelayComputation(locality, st, typeanalysis, gft);
- delaycomp.doAnalysis();
+ delaycomp=new DCWrapper(locality, st, typeanalysis, gft);
dc=delaycomp.getConflicts();
recorddc=new DiscoverConflicts(locality, st, typeanalysis, delaycomp.getCannotDelayMap(), true, true, null);
recorddc.doAnalysis();
if (state.SINGLETM) {
outmethodheader.println("#include \"tm.h\"");
outmethodheader.println("#include \"delaycomp.h\"");
+ outmethodheader.println("#include \"inlinestm.h\"");
}
if (state.ABORTREADERS) {
outmethodheader.println("#include \"abortreaders.h\"");
}
if (state.ARRAYPAD)
outclassdefs.println(" int paddingforarray;");
+ if (state.DUALVIEW) {
+ outclassdefs.println(" int arrayversion;");
+ }
outclassdefs.println(" int ___length___;");
outclassdefs.println("};\n");
for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
FlatNode fn=fnit.next();
if (fn.kind()==FKind.FlatAtomicEnterNode&&
- locality.getAtomic(lb).get(fn.getPrev(0)).intValue()==0) {
+ locality.getAtomic(lb).get(fn.getPrev(0)).intValue()==0&&
+ delaycomp.needsFission(lb, (FlatAtomicEnterNode) fn)) {
//We have an atomic enter
FlatAtomicEnterNode faen=(FlatAtomicEnterNode) fn;
Set<FlatNode> exitset=faen.getExits();
//turn off write barrier generation
wb.turnoff();
state.SINGLETM=false;
- if (state.DUALVIEW)
- versionincrement=true;
generateCode(faen, fm, lb, exitset, output, false);
- if (state.DUALVIEW)
- versionincrement=false;
state.SINGLETM=true;
//turn on write barrier generation
wb.turnon();
// initialize thread-local var to a non-zero, invalid address
output.println(" seseCaller = (SESEcommon*) 0x2;");
-
HashSet<FlatNode> exitset=new HashSet<FlatNode>();
exitset.add(seseExit);
-
generateCode(fsen.getNext(0), fm, null, exitset, output, true);
-
output.println("}\n\n");
}
else
type=elementtype.getSafeSymbol()+" ";
if (firstpass) {
- output.println("STOREARRAY("+src+","+index+","+type+");");
+ output.println("STOREARRAY("+src+","+index+","+type+")");
} else {
output.println("{");
output.println(" struct ArrayObject *array;");
output.println("counter_reset_pointer=&atomiccounter"+sandboxcounter+";");
}
- if (state.DELAYCOMP) {
+ if (state.DELAYCOMP&&delaycomp.needsFission(lb, faen)) {
AtomicRecord ar=atomicmethodmap.get(faen);
//copy in
for(Iterator<TempDescriptor> tmpit=ar.livein.iterator();tmpit.hasNext();) {
if (locality.getAtomic(lb).get(faen).intValue()>0)
return;
//store the revert list before we lose the transaction object
- String revertptr=null;
+
if (state.DSM) {
- revertptr=generateTemp(fm, reverttable.get(lb),lb);
+ String revertptr=generateTemp(fm, reverttable.get(lb),lb);
output.println(revertptr+"=revertlist;");
- }
- if (state.DELAYCOMP) {
- AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
-
- //do call
- output.println("if (transCommit((void (*)(void *, void *, void *))&"+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+")) {");
- } else
output.println("if (transCommit()) {");
- /* Transaction aborts if it returns true */
- output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
-
- output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
- if (state.DSM) {
+ output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
+ output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
output.println("} else {");
/* Need to commit local object store */
output.println("while ("+revertptr+") {");
output.println("COMMIT_OBJ("+revertptr+");");
output.println(revertptr+"=tmpptr;");
output.println("}");
+ output.println("}");
+ return;
}
- output.println("}");
- if (state.DELAYCOMP) {
- //copy out
- AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
- output.println("else {");
- for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
- TempDescriptor tmp=tmpit.next();
- output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
- }
+
+ if (!state.DELAYCOMP) {
+ //Normal STM stuff
+ output.println("if (transCommit()) {");
+ /* Transaction aborts if it returns true */
+ output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
+ output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
output.println("}");
+ } else {
+ if (delaycomp.optimizeTrans(lb, faen.getAtomicEnter())&&(!state.STMARRAY||state.DUALVIEW)) {
+ AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
+ output.println("LIGHTWEIGHTCOMMIT("+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+", transretry"+faen.getAtomicEnter().getIdentifier()+");");
+ //copy out
+ for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
+ }
+ } else if (delaycomp.needsFission(lb, faen.getAtomicEnter())) {
+ AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
+ //do call
+ output.println("if (transCommit((void (*)(void *, void *, void *))&"+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+")) {");
+ output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
+ output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
+ output.println("}");
+ //copy out
+ output.println("else {");
+ for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
+ TempDescriptor tmp=tmpit.next();
+ output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
+ }
+ output.println("}");
+ } else {
+ output.println("if (transCommit(NULL, NULL, NULL, NULL)) {");
+ output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
+ output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
+ output.println("}");
+ }
}
}
if (state.SINGLETM) {
//Single machine transaction case
String dst=generateTemp(fm, fen.getDst(),lb);
- if ((!state.STMARRAY)||(!wb.needBarrier(fen))||locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())==LocalityAnalysis.SCRATCH||locality.getAtomic(lb).get(fen).intValue()==0) {
+ if ((!state.STMARRAY)||(!wb.needBarrier(fen))||locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())==LocalityAnalysis.SCRATCH||locality.getAtomic(lb).get(fen).intValue()==0||
+ (state.READSET&&!dc.getNeedGet(lb, fen))) {
output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
} else {
output.println("STMGETARRAY("+dst+", "+ generateTemp(fm,fen.getSrc(),lb)+", "+generateTemp(fm, fen.getIndex(),lb)+", "+type+");");
}
output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
}
- if (versionincrement) {
- output.println("VERSIONINCREMENT("+generateTemp(fm, fsen.getDst(),lb)+","+generateTemp(fm, fsen.getIndex(),lb)+","+type+");");
- }
}
protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
public boolean DCOPTS=false;
public boolean DELAYCOMP=false;
public boolean DUALVIEW=false;
+ public boolean HYBRID=false;
//Other options
public int CORENUM = 1;
public String structfile;
state.STMARRAY=true;
else if (option.equals("-dualview"))
state.DUALVIEW=true;
+ else if (option.equals("-hybrid"))
+ state.HYBRID=true;
else if (option.equals("-flatirtasks")) {
state.FLATIRGRAPH=true;
state.FLATIRGRAPHTASKS=true;
ABORT
#ifdef DUALVIEW
-#define DVGETLOCK(x) if (!addwrobject) { \
- unsigned int * objlock=&(&((objheader_t *)x)[-1])->lock; \
+/* Try to grab object lock...If we get it, check object access
+ version and abort on mismatch */
+
+#define DVGETLOCK if (!addwrobject) { \
+ unsigned int * objlock=&(&((objheader_t *)mainao)[-1])->lock; \
if(!rwread_trylock(objlock)) { \
ABORT; \
} \
rwread_unlock(objlock); \
}
-//not finished...if we can't get the lock, it is okay if it is in our access set
+/*not finished...if we can't get the lock, it is okay if it is in our
+ access set*/
+
#define DVCHECKLOCK(x) \
unsigned int * objlock=&(&((objheader_t *)x)[-1])->lock; \
if (objlock<=0) { \
- if (dc_t_chashSearch(x)==NULL) { \
+ if (!dc_t_chashSearch(x)) { \
ABORTREAD; \
} \
}
+
+#define DVSETINDEX \
+ dirwrindex[numoidwrlocked]=-1;
+
#else
-#define DVGETLOCK(x)
+#define DVSETINDEX
+#define DVGETLOCK
#define DVCHECKLOCK(x)
#define DVRELEASELOCK(x)
#endif
+
#if defined(DELAYCOMP)&&!defined(DUALVIEW)
#define READCHECK \
else if (dc_t_chashSearchArray(mainao,j)) { \
#define READCHECK
#endif
+ /* This code checks arrays to try to lock them if dirty or check
+ later if they were only read. */
+
#define PROCESSARRAY \
int type=((int *)cachedobj)[0]; \
if (type>=NUMCLASSES) { \
unsigned int status; \
GETLOCKVAL(status, transao, j); \
if (status==STMDIRTY) { \
- DVGETLOCK(mainao); \
+ DVGETLOCK; \
unsigned int * lockptr; \
GETLOCKPTR(lockptr, mainao,j); \
if (likely(write_trylock(lockptr))) { \
} \
} \
if (addwrobject) { \
+ DVSETINDEX \
dirwrlocked[numoidwrlocked++] = objptr; \
} \
if (addrdobject) { \
} else
+ /** This code allows us to skip the expensive checks in some cases */
+
#ifdef DUALVIEW
#define QUICKCHECK { \
objheader_t * head=&((objheader_t *)mainao)[-1]; \
((objheader_t *)transao)[-1].version==head->version) \
continue; \
}
+#define ARRAYCHECK \
+ if (transao->arrayversion!=mainao->arrayversion) \
+ ABORT
#else
#define QUICKCHECK
+#define ARRAYCHECK
#endif
-
+
#define READARRAYS \
for(i=0; i<numoidrdlockedarray; i++) { \
struct ArrayObject * transao=(struct ArrayObject *) oidrdlockedarray[i]; \
struct ArrayObject * mainao=(struct ArrayObject *) transao->___objlocation___; \
+ ARRAYCHECK; \
QUICKCHECK; \
DVCHECKLOCK(mainao); \
int lowoffset=(transao->lowindex); \
dirwrlocked[numoidwrtotal]=objptr; \
dirwrindex[numoidwrtotal++]=intkey; \
} else { \
- unsigned int lockval; \
- GETLOCKVAL(lockval, valptr, intkey); \
- if (lockval!=STMDIRTY) { \
- /*have to abort to avoid deadlock*/ \
- transAbortProcess(oidwrlocked, numoidwrtotal, dirwrindex, numoidwrlocked); \
- ABORTSTAT1; \
- freearrays; \
- if (softabort) \
- return TRANS_SOFT_ABORT; \
- else \
- return TRANS_ABORT; \
- } \
+ chashlistnode_t *node = &c_table[(((unsigned INTPTR)objptr) & c_mask)>>4]; \
+ do { \
+ if(node->key == objptr) { \
+ unsigned int lockval; \
+ GETLOCKVAL(lockval, ((struct ArrayObject *)node->val), intkey); \
+ if (lockval!=STMDIRTY) { \
+ /*have to abort to avoid deadlock*/ \
+ transAbortProcess(oidwrlocked, numoidwrtotal, dirwrindex, numoidwrlocked); \
+ ABORTSTAT1; \
+ freearrays; \
+ if (softabort) \
+ return TRANS_SOFT_ABORT; \
+ else \
+ return TRANS_ABORT; \
+ } \
+ break; \
+ } \
+ node = node->next; \
+ if(node==NULL) { \
+ transAbortProcess(oidwrlocked, numoidwrtotal, dirwrindex, numoidwrlocked); \
+ ABORTSTAT1; \
+ freearrays; \
+ if (softabort) \
+ return TRANS_SOFT_ABORT; \
+ else \
+ return TRANS_ABORT; \
+ } \
+ } while(1); \
} \
} else
/* Inner loop to traverse the linked list of the cache lookupTable */ \
while(likely(dc_curr != NULL)) { \
/*if the first bin in hash table is empty */ \
- void *valptr=dc_curr->val; \
- objheader_t * headeraddr=&((objheader_t *) valptr)[-1]; \
void *objptr=dc_curr->key; \
objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t)); \
ARRAYLOCK \
#define ACCESSLOCKS
#endif
+#ifdef DELAYCOMP
+void lwreset(dchashlistnode_t *dc_curr) {
+ dchashlistnode_t *ptr = dc_c_table;
+ dchashlistnode_t *top=&ptr[dc_c_size];
+ dchashlistnode_t *tmpptr=dc_c_list;
+ int reset=1;
+ while(tmpptr!=NULL) {
+ dchashlistnode_t *next=tmpptr->lnext;
+ if (reset) {
+ if (tmpptr==dc_curr) {
+ reset=0;
+ } else {
+ struct ___Object___ * objptr=tmpptr->key;
+ objheader_t *header=&((objheader_t *)objptr)[-1];
+ if (objptr->type>=NUMCLASSES) {
+ rwwrite_unlock(&header->lock);
+ } else {
+ write_unlock(&header->lock);
+ }
+ }
+ }
+ if (tmpptr>=ptr&&tmpptr<top) {
+ //zero in list
+ tmpptr->key=NULL;
+ tmpptr->next=NULL;
+ }
+ tmpptr=next;
+ }
+ while(dc_c_structs->next!=NULL) {
+ dcliststruct_t *next=dc_c_structs->next;
+ free(dc_c_structs);
+ dc_c_structs=next;
+ }
+ dc_c_structs->num = 0;
+ dc_c_numelements = 0;
+ dc_c_list=NULL;
+ ptrstack.count=0;
+ primstack.count=0;
+ branchstack.count=0;
+}
+#endif
+
/* ==================================================
* traverseCache
* - goes through the transaction cache and
return TRANS_ABORT;
}
#if DELAYCOMP
- } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) {
+ } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))) {
//couldn't get lock because we already have it
//check if it is the right version number
if (version!=header->version) {
unsigned int version=rd_curr->version;
struct ___Object___ * objptr=rd_curr->key;
objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t));
-#ifdef STMARRAY
- int isobject=objptr->type<NUMCLASSES;
- if(likely((isobject&&header->lock>0)||(!isobject&&header->lock==RW_LOCK_BIAS))) {
-#else
if(header->lock>0) {
-#endif
- //object is not locked
+ //object is not write locked
if (unlikely(version!=header->version)) {
//have to abort
transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
#endif
//check normal table
#ifdef STMARRAY
- if (likely(isobject||header->lock==(RW_LOCK_BIAS-1))) {
+ if (likely(objptr->type>=NUMCLASSES||header->lock==(RW_LOCK_BIAS-1))) {
#else
{
#endif
return TRANS_ABORT;
}
#ifdef DELAYCOMP
- } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) {
+ } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))) {
//couldn't get lock because we already have it
//check if it is the right version number
if (version!=header->version) {
int version=rd_curr->version;
struct ___Object___ * objptr=rd_curr->key;
objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t));
-#ifdef STMARRAY
- int isobject=objptr->type<NUMCLASSES;
- if(likely((isobject&&header->lock>0)||(!isobject&&header->lock==RW_LOCK_BIAS))) {
-#else
- if(likely(header->lock>0)) { //object is not locked
-#endif
+ if(likely(header->lock>0)) { //object is not write locked
if (unlikely(version!=header->version)) {
//have to abort
transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked));
#endif
//check normal table
#ifdef STMARRAY
- if (likely(isobject||header->lock==(RW_LOCK_BIAS-1))) {
+ if (likely(objptr->type>=NUMCLASSES||header->lock==(RW_LOCK_BIAS-1))) {
#else
{
#endif
#endif
} else
#endif
- write_unlock(&header->lock);
+ write_unlock(&header->lock);
}
#if defined(STMARRAY)&&defined(DELAYCOMP)&&!defined(DUALVIEW)
//release access locks
rwwrite_unlock(&header->lock);
} else {
header->version++;
+#ifdef DUALVIEW
+ ((struct ArrayObject*)dst)->arrayversion++;
+#endif
rwconvert_unlock(&header->lock);
}
}
#define RESTOREARRAY(x,z) {x=arraystack.array[arraystack.maxcount];z=arraystack.index[arraystack.maxcount++];}
-#define STOREARRAY(x,z,t) {void * y=COMPOID(x); int ii=z;arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=ii; dc_t_chashInsertOnceArray(y,(ii*sizeof(t))>>INDEXSHIFT,y);}
-
-#define STOREARRAYNOLOCK(x,z) {void * y=COMPOID(x); arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z;}
-
-#define STOREARRAYNOTRANS(x,z,t) {void * y=x; int ii=z; arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=ii; dc_t_chashInsertOnceArray(y,(ii*sizeof(t))>>INDEXSHIFT,y);}
-
-#define STOREARRAYNOLOCKNOTRANS(x,z) {void * y=x; arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z; }
+#define STOREARRAY(x,z,t) {void * y=COMPOID(x); int ii=z;arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=ii; dc_t_chashInsertOnceArray(y,(ii*sizeof(t))>>INDEXSHIFT);}
//Pointers
#define RESTOREPTR(x) x=ptrstack.array[ptrstack.maxcount++];
-#define STOREPTR(x) {void * y=COMPOID(x); ptrstack.array[ptrstack.count++]=y; dc_t_chashInsertOnce(y,y);}
+#define STOREPTR(x) {void * y=COMPOID(x); ptrstack.array[ptrstack.count++]=y; dc_t_chashInsertOnce(y);}
#define STOREPTRNOLOCK(x) {void * y=COMPOID(x); ptrstack.array[ptrstack.count++]=y; }
-#define STOREPTRNOTRANS(x) {void * y=x; ptrstack.array[ptrstack.count++]=y; dc_t_chashInsertOnce(y,y);}
-
-#define STOREPTRNOLOCKNOTRANS(x) {void * y=x; ptrstack.array[ptrstack.count++]=y; }
-
//Branches
#define RESTOREBRANCH(loc) (branchstack.array[branchstack.count++])
#ifndef INLINESTM_H
#define INLINESTM_H
-#ifdef DELAYCOMP
+#if defined(DELAYCOMP)&&(!defined(STMARRAY)||defined(DUALVIEW))
#ifndef READSET
#define CHECKREADS(x) 0
#endif
+#ifdef TRANSSTATS
+#define TRANSWRAP(x) x
+#else
+#define TRANSWRAP(x)
+#endif
+
#define LIGHTWEIGHTCOMMIT(commitmethod, primitives, locals, params, label) \
if (GETLOCKS()||CHECKREADS()) { \
+ TRANSWRAP(numTransAbort++;); \
if (unlikely(needtocollect)) checkcollect(&___locals___); \
goto label; \
} \
branchstack.count=0; \
commitmethod(params, locals, primitives); \
RELEASELOCKS(); \
- FREELIST();
+ FREELIST(); \
+ TRANSWRAP(numTransCommit++;);
+
#ifdef READSET
static inline int CHECKREADS() {
objheader_t *header=&((objheader_t *)objptr)[-1];
#ifdef STMARRAY
if (objptr->type>=NUMCLASSES) {
+ ((struct ArrayObject *)objptr)->arrayversion++;
+ header->version++;
rwwrite_unlock(&header->lock);
} else {
#endif
+ header->version++;
write_unlock(&header->lock);
#ifdef STMARRAY
}
int nSoftAbortAbort = 0;
#endif
-void * A_memcpy (void * dest, const void * src, size_t count) {
- int off=0;
+void A_memcpy (void * dest, const void * src, size_t count) {
+#if 0
+ const char *p=src;
+ char *q=dest;
+ size_t nq=count>>3;
+ asm volatile("cld; rep; movsq; mov %3, %%ecx; rep; movsb":"+c"(nq), "+S"(p), "+D"(q):"r"((unsigned int)(count&7)));
+#else
INTPTR *desti=(INTPTR *)dest;
INTPTR *srci=(INTPTR *)src;
//word copy
- while(count>=sizeof(INTPTR)) {
- desti[off]=srci[off];
- off+=1;
- count-=sizeof(INTPTR);
+ int count2=count>>INTPTRSHIFT;
+ for(;0<count2;count2--) {
+ *desti++=*srci++;
}
- off*=sizeof(INTPTR);
//byte copy
- while(count>0) {
- ((char *)dest)[off]=((char *)src)[off];
- off++;
- count--;
+ count=count&(sizeof(INTPTR)-1);
+
+ char *dstc=(char *)desti;
+ char *srcc=(char *)srci;
+ for(;0<count;count--) {
+ *dstc++=*srcc++;
}
+#endif
}
/* ==================================================
#include <stdio.h>
-inline void initdsmlocks(volatile unsigned int *addr) {
- (*addr) = SWAP_LOCK_BIAS;
-}
-
/*
int write_trylock(volatile unsigned int *lock) {
int retval=0;
".previous\n" \
"661:\n\tlock; "
-void initdsmlocks(volatile unsigned int *addr);
+static inline initdsmlocks(volatile unsigned int *addr) {
+ (*addr) = SWAP_LOCK_BIAS;
+}
//int write_trylock(volatile unsigned int *lock);
//void write_unlock(volatile unsigned int *lock);
return c;
}
+static inline unsigned long cas(volatile unsigned int* ptr) {
+ unsigned int prev;
+ __asm__ __volatile__("lock;"
+ "cmpxchgl %1, %2;"
+ : "=a"(prev)
+ : "r"(0), "m"(*ptr), "a"(RW_LOCK_BIAS)
+ : "memory");
+ return prev==RW_LOCK_BIAS;
+}
+
+
#define atomic_read(v) (*v)
static inline int rwread_trylock(volatile unsigned int *lock) {
atomic_dec(lock);
- if (likely(atomic_read(lock) >= 0))
+ if (likely(atomic_read(lock) >=0 ))
return 1; //can aquire a new read lock
atomic_inc(lock);
return 0; //failure
}
static inline int rwwrite_trylock(volatile unsigned int *lock) {
- if (likely(atomic_sub_and_test(RW_LOCK_BIAS, lock))) {
- return 1; // get a write lock
+ if (likely(cas(lock))) {
+ return 1;
}
+ // if (likely(atomic_sub_and_test(RW_LOCK_BIAS, lock))) {
+ // return 1; // get a write lock
+ //}
atomic_add(RW_LOCK_BIAS, lock);
return 0; // failed to acquire a write lock
}
void rd_t_chashInsertOnce(void * key, unsigned int version) {
rdchashlistnode_t *ptr;
- if (key==NULL)
+ if (unlikely(key==NULL))
return;
- if(rd_c_numelements > (rd_c_threshold)) {
+ if(unlikely(rd_c_numelements > (rd_c_threshold))) {
//Resize
unsigned int newsize = rd_c_size << 1;
rd_t_chashResize(newsize);
}
//Store objects and their pointers into hash
-void dc_t_chashInsertOnce(void * key, void *val) {
+void dc_t_chashInsertOnce(void * key) {
dchashlistnode_t *ptr;
if (unlikely(key==NULL)) {
unsigned int newsize = dc_c_size << 1;
dc_t_chashResize(newsize);
}
-
ptr = &dc_c_table[(((unsigned INTPTR)key)&dc_c_mask)>>4];
if(likely(ptr->key==0)) {
ptr->key=key;
- ptr->val=val;
#if defined(STMARRAY)&&!defined(DUALVIEW)
ptr->intkey=-1;
#endif
node->intkey=-1;
#endif
node->key = key;
- node->val = val;
node->next = ptr->next;
ptr->next=node;
node->lnext=dc_c_list;
#if defined(STMARRAY)&&!defined(DUALVIEW)
//Store objects and their pointers into hash
-void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) {
+void dc_t_chashInsertOnceArray(void * key, unsigned int intkey) {
dchashlistnode_t *ptr;
if (unlikely(key==NULL))
if(ptr->key==0) {
ptr->key=key;
ptr->intkey=intkey;
- ptr->val=val;
ptr->lnext=dc_c_list;
dc_c_list=ptr;
dc_c_numelements++;
}
node->key = key;
node->intkey = intkey;
- node->val = val;
node->next = ptr->next;
ptr->next=node;
node->lnext=dc_c_list;
#if defined(STMARRAY)&!defined(DUALVIEW)
tmp->intkey = intkey;
#endif
- tmp->val = curr->val;
tmp->lnext=dc_c_list;
dc_c_list=tmp;
} /*
}
// Search for an address for a given oid
-INLINE void * dc_t_chashSearch(void * key) {
+INLINE int dc_t_chashSearch(void * key) {
//REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
do {
if(node->key == key) {
- return node->val;
+ return 1;
}
node = node->next;
} while(node != NULL);
- return NULL;
+ return 0;
}
#if defined(STMARRAY)&!defined(DUALVIEW)
// Search for an address for a given oid
-INLINE void * dc_t_chashSearchArray(void * key, unsigned int intkey) {
+INLINE int dc_t_chashSearchArray(void * key, unsigned int intkey) {
//REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key^intkey) & dc_c_mask)>>4];
do {
if(node->key == key && node->intkey==intkey) {
- return node->val;
+ return 1;
}
node = node->next;
} while(node != NULL);
- return NULL;
+ return 0;
}
#endif
c_loadfactor = loadfactor;
c_size = size;
c_threshold=size*loadfactor;
- c_mask = (size << 4)-1;
+#ifdef BIT64
+ c_mask = ((size << 4)-1)&~(15UL);
+#else
+ c_mask = ((size << 4)-1)&~15;
+#endif
c_structs=calloc(1, sizeof(cliststruct_t));
c_numelements = 0; // Initial number of elements in the hash
c_list=NULL;
#if defined(STMARRAY)&&!defined(DUALVIEW)
unsigned int intkey;
#endif
- void * val; //this can be cast to another type or used to point to a larger structure
struct dchashlistnode *next;
struct dchashlistnode *lnext;
} dchashlistnode_t;
extern __thread dcliststruct_t *dc_c_structs;
void dc_t_chashCreate(unsigned int size, double loadfactor);
-void dc_t_chashInsertOnce(void * key, void *val);
-void * dc_t_chashSearch(void * key);
+void dc_t_chashInsertOnce(void * key);
+int dc_t_chashSearch(void * key);
unsigned int dc_t_chashResize(unsigned int newsize);
void dc_t_chashDelete();
void dc_t_chashreset();
__attribute__((pure)) void *transReadOnly(void *);
#endif
#ifdef DELAYCOMP
+void lwreset(dchashlistnode_t *dc_curr);
int transCommit(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params);
int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params);
int alttraverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params);
#define NUMPTRS 100
-#define INITIALHEAPSIZE 512*1024*1024L
+#define INITIALHEAPSIZE 2048*1024*1024L
#define GCPOINT(x) ((INTPTR)((x)*0.99))
/* This define takes in how full the heap is initially and returns a new heap size to use */
#define HEAPSIZE(x,y) ((INTPTR)(x+y))*2
#ifndef INTPTR
#ifdef BIT64
#define INTPTR long
+#define INTPTRSHIFT 3
#else
#define INTPTR int
+#define INTPTRSHIFT 2
#endif
#endif
echo -transstats generates transaction stats on commits and aborts
echo -inlineatomic depth inline methods inside of transactions to specified depth
echo "-stmarray partial array treatment"
+echo "-dualview dual view of arrays"
+echo "-hybrid use fission only when it looks like a good choice"
echo
echo DSM options
echo -dsm distributed shared memory
DSMRECOVERY=false
FASTMEMCPY=false
STMARRAY=false
+DUALVIEW=false
STM=false
NOJAVA=false
CHECKFLAG=false
JAVAOPTS="$JAVAOPTS -stmarray"
EXTRAOPTIONS="$EXTRAOPTIONS -DSTMARRAY"
STMARRAY=true
+elif [[ $1 = '-dualview' ]]
+then
+JAVAOPTS="$JAVAOPTS -dualview"
+EXTRAOPTIONS="$EXTRAOPTIONS -DDUALVIEW"
+DUALVIEW=true
elif [[ $1 = '-readset' ]]
then
JAVAOPTS="$JAVAOPTS -readset"
then
JAVAOPTS="$JAVAOPTS -delaycomp"
EXTRAOPTIONS="$EXTRAOPTIONS -DDELAYCOMP"
+elif [[ $1 = '-hybrid' ]]
+then
+JAVAOPTS="$JAVAOPTS -hybrid"
+EXTRAOPTIONS="$EXTRAOPTIONS -DHYBRID"
elif [[ $1 = '-minimize' ]]
then
JAVAOPTS="$JAVAOPTS -minimize"
EXTRAOPTIONS="$EXTRAOPTIONS -O0"
elif [[ $1 = '-optimize' ]]
then
-EXTRAOPTIONS="$EXTRAOPTIONS -O9"
+EXTRAOPTIONS="$EXTRAOPTIONS -O3"
elif [[ $1 = '-thread' ]]
then
JAVAOPTS="$JAVAOPTS -thread"
#if ! ${ROBUSTROOT}/ourjava -Xms5m -Xmx100m $JAVAFORWARDOPTS -classpath $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
if ! $NOJAVA
then
-if ! ${ROBUSTROOT}/ourjava -Xms50m -Xmx1500m $JAVAFORWARDOPTS -classpath $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
+if ! ${ROBUSTROOT}/ourjava -Xms150m -Xmx2500m $JAVAFORWARDOPTS -classpath $ROBUSTROOT/../cup/:$ROBUSTROOT Main.Main -classlibrary \
$ROBUSTROOT/ClassLibrary/ -classlibrary $ROBUSTROOT/ClassLibrary/gnu/ -dir $BUILDDIR -precise \
$JAVAOPTS $SRCFILES
then exit $?