From: bdemsky Date: Fri, 6 Nov 2009 06:36:30 +0000 (+0000) Subject: changes to support inlined fission transactions X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ebe47139d76d897125af6a82a4f8bf95ed4abe22;p=IRC.git changes to support inlined fission transactions --- diff --git a/Robust/src/Analysis/Locality/DCWrapper.java b/Robust/src/Analysis/Locality/DCWrapper.java index f7d78f0f..b28a14e0 100644 --- a/Robust/src/Analysis/Locality/DCWrapper.java +++ b/Robust/src/Analysis/Locality/DCWrapper.java @@ -173,7 +173,7 @@ public class DCWrapper { for(Iterator 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; diff --git a/Robust/src/Analysis/Locality/DelayComputation.java b/Robust/src/Analysis/Locality/DelayComputation.java index 4d67cb50..dd8defa0 100644 --- a/Robust/src/Analysis/Locality/DelayComputation.java +++ b/Robust/src/Analysis/Locality/DelayComputation.java @@ -108,6 +108,40 @@ public class DelayComputation { } } + public HashSet computeWriteSet(LocalityBinding lb) { + HashSet writeset=new HashSet(); + Set storeset=livecode(lb); + HashSet delayedset=getNotReady(lb); + Hashtable>> fnmap=dcopts.getMap(lb); + for(Iterator fnit=delayedset.iterator();fnit.hasNext();) { + FlatNode fn=fnit.next(); + Hashtable> tempmap=fnmap.get(fn); + if (fn.kind()==FKind.FlatSetElementNode) { + FlatSetElementNode fsen=(FlatSetElementNode) fn; + Set tfpset=tempmap.get(fsen.getDst()); + if (tfpset!=null) { + for(Iterator 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 tfpset=tempmap.get(fsfn.getDst()); + if (tfpset!=null) { + for(Iterator tfpit=tfpset.iterator();tfpit.hasNext();) { + TempFlatPair tfp=tfpit.next(); + if (storeset.contains(tfp.f)) + writeset.add(tfp.f); + } + } + } + } + return writeset; + } + + public HashSet getNotReady(LocalityBinding lb) { return notreadymap.get(lb); } diff --git a/Robust/src/Analysis/Locality/DiscoverConflicts.java b/Robust/src/Analysis/Locality/DiscoverConflicts.java index ac58bf46..1d32d9f7 100644 --- a/Robust/src/Analysis/Locality/DiscoverConflicts.java +++ b/Robust/src/Analysis/Locality/DiscoverConflicts.java @@ -23,6 +23,8 @@ public class DiscoverConflicts { Hashtable> transreadmap; Hashtable> twritemap; Hashtable> writemap; + Hashtable> getmap; + Hashtable> srcmap; Hashtable> leftsrcmap; Hashtable> rightsrcmap; @@ -49,6 +51,7 @@ public class DiscoverConflicts { twritemap=new Hashtable>(); writemap=new Hashtable>(); } + getmap=new Hashtable>(); this.gft=gft; } @@ -71,6 +74,7 @@ public class DiscoverConflicts { twritemap=new Hashtable>(); writemap=new Hashtable>(); } + getmap=new Hashtable>(); this.gft=gft; } @@ -95,13 +99,12 @@ public class DiscoverConflicts { for(Iterator 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 set=new HashSet(); for(Iterator it=transreadmap.get(lb).iterator();it.hasNext();) { TempFlatPair tfp=it.next(); @@ -118,6 +121,31 @@ public class DiscoverConflicts { twritemap.put(lb, set); } } + + private void computeneedsarrayget(LocalityBinding lb, Hashtable>> fnmap) { + Set writeset=(state.READSET&&gft!=null)?twritemap.get(lb):treadmap.get(lb); + FlatMethod fm=state.getMethodFlat(lb.getMethod()); + HashSet needsget=new HashSet(); + for(Iterator fnit=fm.getNodeSet().iterator();fnit.hasNext();) { + FlatNode fn=fnit.next(); + Hashtable atomictable=locality.getAtomic(lb); + if (atomictable.get(fn).intValue()>0&&fn.kind()==FKind.FlatElementNode) { + FlatElementNode fen=(FlatElementNode)fn; + Set tfpset=fnmap.get(fen).get(fen.getSrc()); + if (tfpset!=null) { + for(Iterator 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. @@ -168,6 +196,12 @@ public class DiscoverConflicts { 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); @@ -209,7 +243,6 @@ public class DiscoverConflicts { if (atomictable.get(fn).intValue()>0) { Hashtable> tmap=fnmap.get(fn); switch(fn.kind()) { - //We might need to translate arguments to pointer comparison case FKind.FlatOpNode: { @@ -315,6 +348,9 @@ public class DiscoverConflicts { } } } + //Update results + setNeedReadTrans(lb); + computeneedsarrayget(lb, fnmap); } public boolean outofscope(TempFlatPair tfp) { diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 5299961b..ea95749a 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -19,6 +19,7 @@ import Analysis.TaskStateAnalysis.TaskIndex; 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; @@ -70,9 +71,8 @@ public class BuildCode { 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) { @@ -118,8 +118,7 @@ public class BuildCode { //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(); @@ -184,6 +183,7 @@ public class BuildCode { 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\""); @@ -643,6 +643,9 @@ public class BuildCode { } if (state.ARRAYPAD) outclassdefs.println(" int paddingforarray;"); + if (state.DUALVIEW) { + outclassdefs.println(" int arrayversion;"); + } outclassdefs.println(" int ___length___;"); outclassdefs.println("};\n"); @@ -1594,7 +1597,8 @@ public class BuildCode { for(Iterator 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 exitset=faen.getExits(); @@ -1661,11 +1665,7 @@ public class BuildCode { //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(); @@ -2097,12 +2097,9 @@ public class BuildCode { // initialize thread-local var to a non-zero, invalid address output.println(" seseCaller = (SESEcommon*) 0x2;"); - HashSet exitset=new HashSet(); exitset.add(seseExit); - generateCode(fsen.getNext(0), fm, null, exitset, output, true); - output.println("}\n\n"); } @@ -2405,7 +2402,7 @@ public class BuildCode { 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;"); @@ -2996,7 +2993,7 @@ public class BuildCode { 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 tmpit=ar.livein.iterator();tmpit.hasNext();) { @@ -3066,23 +3063,13 @@ public class BuildCode { 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+") {"); @@ -3091,17 +3078,46 @@ public class BuildCode { 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 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 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 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("}"); + } } } @@ -3816,7 +3832,8 @@ public class BuildCode { 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+");"); @@ -3951,9 +3968,6 @@ public class BuildCode { } 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) { diff --git a/Robust/src/IR/State.java b/Robust/src/IR/State.java index 5cb080ec..f69247d1 100644 --- a/Robust/src/IR/State.java +++ b/Robust/src/IR/State.java @@ -101,6 +101,7 @@ public class State { 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; diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index 8b6c5a67..4a3cc7c3 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -123,6 +123,8 @@ public class Main { 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; diff --git a/Robust/src/Runtime/STM/commit.c b/Robust/src/Runtime/STM/commit.c index a6e5f38a..a0aa9f68 100644 --- a/Robust/src/Runtime/STM/commit.c +++ b/Robust/src/Runtime/STM/commit.c @@ -299,8 +299,11 @@ int transCommit() { 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; \ } \ @@ -311,20 +314,28 @@ int transCommit() { 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)) { \ @@ -343,6 +354,9 @@ int transCommit() { #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) { \ @@ -356,7 +370,7 @@ int transCommit() { 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))) { \ @@ -380,6 +394,7 @@ int transCommit() { } \ } \ if (addwrobject) { \ + DVSETINDEX \ dirwrlocked[numoidwrlocked++] = objptr; \ } \ if (addrdobject) { \ @@ -388,6 +403,8 @@ int transCommit() { } else + /** This code allows us to skip the expensive checks in some cases */ + #ifdef DUALVIEW #define QUICKCHECK { \ objheader_t * head=&((objheader_t *)mainao)[-1]; \ @@ -395,14 +412,19 @@ int transCommit() { ((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___objlocation___; \ + ARRAYCHECK; \ QUICKCHECK; \ DVCHECKLOCK(mainao); \ int lowoffset=(transao->lowindex); \ @@ -467,18 +489,34 @@ int transCommit() { 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 @@ -518,8 +556,6 @@ int transCommit() { /* 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 \ @@ -557,6 +593,48 @@ int transCommit() { #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&&tmpptrkey=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 @@ -665,7 +743,7 @@ int traverseCache() { 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) { @@ -699,13 +777,8 @@ int traverseCache() { 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->typelock>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)); @@ -734,7 +807,7 @@ int traverseCache() { #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 @@ -870,7 +943,7 @@ int alttraverseCache() { 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) { @@ -903,12 +976,7 @@ int alttraverseCache() { 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->typelock>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)); @@ -935,7 +1003,7 @@ int alttraverseCache() { #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 @@ -1021,7 +1089,7 @@ void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrlocked) { #endif } else #endif - write_unlock(&header->lock); + write_unlock(&header->lock); } #if defined(STMARRAY)&&defined(DELAYCOMP)&&!defined(DUALVIEW) //release access locks @@ -1201,6 +1269,9 @@ void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { rwwrite_unlock(&header->lock); } else { header->version++; +#ifdef DUALVIEW + ((struct ArrayObject*)dst)->arrayversion++; +#endif rwconvert_unlock(&header->lock); } } diff --git a/Robust/src/Runtime/STM/delaycomp.h b/Robust/src/Runtime/STM/delaycomp.h index c5657cfc..ab6ad29a 100644 --- a/Robust/src/Runtime/STM/delaycomp.h +++ b/Robust/src/Runtime/STM/delaycomp.h @@ -47,26 +47,16 @@ extern __thread struct arraylist arraystack; #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++]) diff --git a/Robust/src/Runtime/STM/inlinestm.h b/Robust/src/Runtime/STM/inlinestm.h index 2803cdad..d2f6041f 100644 --- a/Robust/src/Runtime/STM/inlinestm.h +++ b/Robust/src/Runtime/STM/inlinestm.h @@ -1,13 +1,20 @@ #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; \ } \ @@ -16,7 +23,9 @@ branchstack.count=0; \ commitmethod(params, locals, primitives); \ RELEASELOCKS(); \ - FREELIST(); + FREELIST(); \ + TRANSWRAP(numTransCommit++;); + #ifdef READSET static inline int CHECKREADS() { @@ -119,9 +128,12 @@ static inline void RELEASELOCKS() { 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 } diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index 1faa91f1..b9b2935c 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -40,24 +40,30 @@ int nSoftAbortCommit = 0; 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(;00) { - ((char *)dest)[off]=((char *)src)[off]; - off++; - count--; + count=count&(sizeof(INTPTR)-1); + + char *dstc=(char *)desti; + char *srcc=(char *)srci; + for(;0 -inline void initdsmlocks(volatile unsigned int *addr) { - (*addr) = SWAP_LOCK_BIAS; -} - /* int write_trylock(volatile unsigned int *lock) { int retval=0; diff --git a/Robust/src/Runtime/STM/stmlock.h b/Robust/src/Runtime/STM/stmlock.h index 1898f2de..d75d3f21 100644 --- a/Robust/src/Runtime/STM/stmlock.h +++ b/Robust/src/Runtime/STM/stmlock.h @@ -16,7 +16,9 @@ ".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); @@ -79,20 +81,34 @@ static inline int atomic_sub_and_test(int i, volatile unsigned int *v) { 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 } diff --git a/Robust/src/Runtime/STM/stmlookup.c b/Robust/src/Runtime/STM/stmlookup.c index e8f5d562..b5e7046b 100644 --- a/Robust/src/Runtime/STM/stmlookup.c +++ b/Robust/src/Runtime/STM/stmlookup.c @@ -70,10 +70,10 @@ void rd_t_chashreset() { 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); @@ -258,7 +258,7 @@ void dc_t_chashreset() { } //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)) { @@ -270,11 +270,9 @@ void dc_t_chashInsertOnce(void * key, void *val) { 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 @@ -309,7 +307,6 @@ void dc_t_chashInsertOnce(void * key, void *val) { node->intkey=-1; #endif node->key = key; - node->val = val; node->next = ptr->next; ptr->next=node; node->lnext=dc_c_list; @@ -319,7 +316,7 @@ void dc_t_chashInsertOnce(void * key, void *val) { #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)) @@ -336,7 +333,6 @@ void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) { 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++; @@ -366,7 +362,6 @@ void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) { } node->key = key; node->intkey = intkey; - node->val = val; node->next = ptr->next; ptr->next=node; node->lnext=dc_c_list; @@ -423,7 +418,6 @@ unsigned int dc_t_chashResize(unsigned int newsize) { #if defined(STMARRAY)&!defined(DUALVIEW) tmp->intkey = intkey; #endif - tmp->val = curr->val; tmp->lnext=dc_c_list; dc_c_list=tmp; } /* @@ -468,34 +462,34 @@ void dc_t_chashDelete() { } // 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 @@ -513,7 +507,11 @@ void t_chashCreate(unsigned int size, double loadfactor) { 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; diff --git a/Robust/src/Runtime/STM/stmlookup.h b/Robust/src/Runtime/STM/stmlookup.h index e2529287..49d9c4a1 100644 --- a/Robust/src/Runtime/STM/stmlookup.h +++ b/Robust/src/Runtime/STM/stmlookup.h @@ -96,7 +96,6 @@ typedef struct dchashlistnode { #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; @@ -118,8 +117,8 @@ extern __thread double dc_c_loadfactor; 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(); diff --git a/Robust/src/Runtime/STM/tm.h b/Robust/src/Runtime/STM/tm.h index edfba6f7..ef8937e3 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -201,6 +201,7 @@ __attribute__((pure)) void *transRead(void *, void *); __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); diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c index 1bc6c255..ac663cff 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -30,7 +30,7 @@ #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 diff --git a/Robust/src/Runtime/runtime.h b/Robust/src/Runtime/runtime.h index d3dcc04a..138fbb5e 100644 --- a/Robust/src/Runtime/runtime.h +++ b/Robust/src/Runtime/runtime.h @@ -17,8 +17,10 @@ extern int failurecount; #ifndef INTPTR #ifdef BIT64 #define INTPTR long +#define INTPTRSHIFT 3 #else #define INTPTR int +#define INTPTRSHIFT 2 #endif #endif diff --git a/Robust/src/buildscript b/Robust/src/buildscript index b6a8b3a5..b9b079e4 100755 --- a/Robust/src/buildscript +++ b/Robust/src/buildscript @@ -11,6 +11,8 @@ echo -dcopts conflict optimizations for transactional memory 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 @@ -89,6 +91,7 @@ DSMFLAG=false DSMRECOVERY=false FASTMEMCPY=false STMARRAY=false +DUALVIEW=false STM=false NOJAVA=false CHECKFLAG=false @@ -208,6 +211,11 @@ then 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" @@ -330,6 +338,10 @@ elif [[ $1 = '-delaycomp' ]] then JAVAOPTS="$JAVAOPTS -delaycomp" EXTRAOPTIONS="$EXTRAOPTIONS -DDELAYCOMP" +elif [[ $1 = '-hybrid' ]] +then +JAVAOPTS="$JAVAOPTS -hybrid" +EXTRAOPTIONS="$EXTRAOPTIONS -DHYBRID" elif [[ $1 = '-minimize' ]] then JAVAOPTS="$JAVAOPTS -minimize" @@ -380,7 +392,7 @@ then EXTRAOPTIONS="$EXTRAOPTIONS -O0" elif [[ $1 = '-optimize' ]] then -EXTRAOPTIONS="$EXTRAOPTIONS -O9" +EXTRAOPTIONS="$EXTRAOPTIONS -O3" elif [[ $1 = '-thread' ]] then JAVAOPTS="$JAVAOPTS -thread" @@ -472,7 +484,7 @@ else #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 $?