From: bdemsky Date: Tue, 27 Oct 2009 00:58:20 +0000 (+0000) Subject: more stm options X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8b760ab64e6b0819c0ad4605698f40bf0616e325;p=IRC.git more stm options --- diff --git a/Robust/src/Analysis/Locality/DelayComputation.java b/Robust/src/Analysis/Locality/DelayComputation.java index 590e5c65..4d67cb50 100644 --- a/Robust/src/Analysis/Locality/DelayComputation.java +++ b/Robust/src/Analysis/Locality/DelayComputation.java @@ -34,7 +34,7 @@ public class DelayComputation { this.gft=gft; this.notreadymap=new Hashtable>(); this.cannotdelaymap=new Hashtable>(); - if (state.STMARRAY) + if (state.STMARRAY&&!state.DUALVIEW) this.derefmap=new Hashtable>(); this.othermap=new Hashtable>(); } @@ -286,7 +286,7 @@ public class DelayComputation { HashSet delayedset=notreadymap.get(lb); HashSet derefset=null; - if (state.STMARRAY) + if (state.STMARRAY&&!state.DUALVIEW) derefset=derefmap.get(lb); HashSet otherset=othermap.get(lb); HashSet cannotdelayset=cannotdelaymap.get(lb); @@ -374,7 +374,7 @@ public class DelayComputation { } if (delayedset.contains(fn)) { - if(state.STMARRAY&&derefset.contains(fn)) { + if(state.STMARRAY&&!state.DUALVIEW&&derefset.contains(fn)) { //FlatElementNodes don't read anything... if (fn.kind()==FKind.FlatSetElementNode) { //check only the source read tmp @@ -555,7 +555,7 @@ public class DelayComputation { Set branchset=revbranchmap.get((FlatCondBranch)fn); for(Iterator brit=branchset.iterator();brit.hasNext();) { FlatNode branchnode=brit.next(); - if (cannotdelay.contains(branchnode)||(state.STMARRAY&&derefset.contains(branchnode))) { + if (cannotdelay.contains(branchnode)||(state.STMARRAY&&!state.DUALVIEW&&derefset.contains(branchnode))) { isnodelay=true; break; } @@ -663,7 +663,7 @@ public class DelayComputation { if (oldtemps.contains(fsen.getDst())) { nodelaytempset.add(fsen.getDst()); //Word Array support requires index - if (state.STMARRAY) { + if (state.STMARRAY&&!state.DUALVIEW) { nodelaytempset.add(fsen.getIndex()); derefset.add(fsen); } @@ -684,7 +684,7 @@ public class DelayComputation { dcopts.getArrays().contains(fen.getSrc().getType())) { nodelaytempset.add(fen.getSrc()); //Word Array support requires index - if (state.STMARRAY) { + if (state.STMARRAY&&!state.DUALVIEW) { nodelaytempset.add(fen.getIndex()); derefset.add(fen); } @@ -736,7 +736,7 @@ public class DelayComputation { }//end of while loop if (lb.getHasAtomic()) { - if (state.STMARRAY) + if (state.STMARRAY&&!state.DUALVIEW) derefmap.put(lb, derefset); cannotdelaymap.put(lb, cannotdelay); } diff --git a/Robust/src/Analysis/Locality/DiscoverConflicts.java b/Robust/src/Analysis/Locality/DiscoverConflicts.java index 775c87eb..ac58bf46 100644 --- a/Robust/src/Analysis/Locality/DiscoverConflicts.java +++ b/Robust/src/Analysis/Locality/DiscoverConflicts.java @@ -169,7 +169,9 @@ public class DiscoverConflicts { } public boolean getNeedWriteTrans(LocalityBinding lb, FlatNode fn) { - return twritemap.get(lb).contains(fn); + if (gft!=null) + return twritemap.get(lb).contains(fn); + else throw new Error(); } public Hashtable>> getMap(LocalityBinding lb) { diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 240fb7f1..d174ec65 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -71,6 +71,8 @@ public class BuildCode { DiscoverConflicts recorddc; DelayComputation delaycomp; CallGraph callgraph; + boolean versionincrement; + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) { this(st, temptovar, typeutil, null, sa, pa, null); @@ -107,7 +109,8 @@ public class BuildCode { } if (state.SINGLETM&&state.DCOPTS) { TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph); - this.dc=new DiscoverConflicts(locality, st, typeanalysis, null); + GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain()); + this.dc=new DiscoverConflicts(locality, st, typeanalysis, gft); dc.doAnalysis(); } if (state.DELAYCOMP) { @@ -637,7 +640,6 @@ public class BuildCode { outclassdefs.println(" int lowindex;"); outclassdefs.println(" int highindex;"); } - if (state.ARRAYPAD) outclassdefs.println(" int paddingforarray;"); @@ -1652,7 +1654,11 @@ 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(); @@ -1737,8 +1743,10 @@ public class BuildCode { if (state.DSM&&lb.isAtomic()) output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");"); else if (this.state.MULTICOREGC) { - output.println("if(gcflag) gc("+localsprefixaddr+");"); - } else + output.println("if(gcflag) gc("+localsprefixaddr+");"); + } else if (state.SINGLETM) { + output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); + } else output.println("if (needtocollect) checkcollect("+localsprefixaddr+");"); } } @@ -2075,7 +2083,9 @@ public class BuildCode { if (callgraph.getAllMethods(md).contains(md)) { if(this.state.MULTICOREGC) { output.println("if(gcflag) gc("+localsprefixaddr+");"); - } else { + } else if (state.SINGLETM) { + output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); + } else { output.println("if (needtocollect) checkcollect("+localsprefixaddr+");"); } } @@ -2155,7 +2165,7 @@ public class BuildCode { if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) { storeset=delaycomp.livecode(lb); genset=new HashSet(); - if (state.STMARRAY) { + if (state.STMARRAY&&!state.DUALVIEW) { refset=new HashSet(); refset.addAll(delaycomp.getDeref(lb)); refset.removeAll(delaycomp.getCannotDelay(lb)); @@ -2166,14 +2176,14 @@ public class BuildCode { genset.addAll(delaycomp.getOther(lb)); } else { genset.addAll(delaycomp.getNotReady(lb)); - if (state.STMARRAY) { + if (state.STMARRAY&&!state.DUALVIEW) { genset.removeAll(refset); } } unionset=new HashSet(); unionset.addAll(storeset); unionset.addAll(genset); - if (state.STMARRAY) + if (state.STMARRAY&&!state.DUALVIEW) unionset.addAll(refset); } @@ -2248,7 +2258,7 @@ public class BuildCode { if (genset==null||genset.contains(current_node)||specialprimitive) generateFlatNode(fm, lb, current_node, output); - if (state.STMARRAY&&refset!=null&&refset.contains(current_node)) { + if (state.STMARRAY&&!state.DUALVIEW&&refset!=null&&refset.contains(current_node)) { //need to acquire lock handleArrayDeref(fm, lb, current_node, output, firstpass); } @@ -2259,7 +2269,7 @@ public class BuildCode { if (wrtmp.getType().isPtr()) { //only lock the objects that may actually need locking if (recorddc.getNeedTrans(lb, current_node)&& - (!state.STMARRAY||!wrtmp.getType().isArray()|| + (!state.STMARRAY||state.DUALVIEW||!wrtmp.getType().isArray()|| wrtmp.getType().getSymbol().equals(TypeUtil.ObjectClass))) { output.println("STOREPTR("+generateTemp(fm, wrtmp,lb)+");/* "+current_node.nodeid+" */"); } else { @@ -2370,7 +2380,7 @@ public class BuildCode { output.println(" struct ArrayObject *array;"); output.println(" int index;"); output.println(" RESTOREARRAY(array,index);"); - output.println(" (("+type+"*)(((char *)&array->___length___)+sizeof(int)))[index]="+fsen.getSrc()+";"); + output.println(" (("+type+"*)(((char *)&array->___length___)+sizeof(int)))[index]="+src+";"); output.println("}"); } } else if (fn.kind()==FKind.FlatElementNode) { @@ -2645,7 +2655,7 @@ public class BuildCode { case FKind.FlatBackEdge: if (state.SINGLETM&&state.SANDBOX&&(locality.getAtomic(lb).get(fn).intValue()>0)) { - output.println("if ((--transaction_check_counter)<=0) checkObjects();"); + output.println("if (unlikely((--transaction_check_counter)<=0)) checkObjects();"); } if (((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { @@ -2653,6 +2663,8 @@ public class BuildCode { output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");"); } else if(this.state.MULTICOREGC) { output.println("if (gcflag) gc("+localsprefixaddr+");"); + } else if (state.SINGLETM) { + output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");"); } else output.println("if (needtocollect) checkcollect("+localsprefixaddr+");"); } else @@ -2907,7 +2919,15 @@ public class BuildCode { public void generateFlatAtomicEnterNode(FlatMethod fm, LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) { /* Check to see if we need to generate code for this atomic */ if (locality==null) { - output.println("pthread_mutex_lock(&atomiclock);"); + if (GENERATEPRECISEGC) { + output.println("if (pthread_mutex_trylock(&atomiclock)!=0) {"); + output.println("stopforgc((struct garbagelist *) &___locals___);"); + output.println("pthread_mutex_lock(&atomiclock);"); + output.println("restartaftergc();"); + output.println("}"); + } else { + output.println("pthread_mutex_lock(&atomiclock);"); + } return; } @@ -3873,6 +3893,9 @@ 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 2e4c037c..5cb080ec 100644 --- a/Robust/src/IR/State.java +++ b/Robust/src/IR/State.java @@ -100,6 +100,7 @@ public class State { public boolean SANDBOX=false; public boolean DCOPTS=false; public boolean DELAYCOMP=false; + public boolean DUALVIEW=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 4b70f6e7..77654238 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -120,6 +120,8 @@ public class Main { state.TAGSTATE=true; else if (option.equals("-stmarray")) state.STMARRAY=true; + else if (option.equals("-dualview")) + state.DUALVIEW=true; else if (option.equals("-flatirtasks")) { state.FLATIRGRAPH=true; state.FLATIRGRAPHTASKS=true; diff --git a/Robust/src/Runtime/STM/array.h b/Robust/src/Runtime/STM/array.h index 7a31bb87..23aaa18f 100644 --- a/Robust/src/Runtime/STM/array.h +++ b/Robust/src/Runtime/STM/array.h @@ -3,7 +3,6 @@ /* Array layout */ #define INDEXSHIFT 5 //must be at least 3 for doubles -//#define DBLINDEXSHIFT INDEXSHIFT-1 //must be at least 3 for doubles #define INDEXLENGTH (1<>INDEXSHIFT)); \ + (*versionptr)++; \ +} diff --git a/Robust/src/Runtime/STM/commit.c b/Robust/src/Runtime/STM/commit.c index 229a4e26..8e47228d 100644 --- a/Robust/src/Runtime/STM/commit.c +++ b/Robust/src/Runtime/STM/commit.c @@ -33,6 +33,12 @@ #define ARRAYDELAYWRAP1(x) #endif +#ifdef DUALVIEW +#define DUALVIEWWRAP(x) x +#else +#define DUALVIEWWRAP(x) +#endif + /* ================================================================ * transCommit * - This function initiates the transaction commit process @@ -79,7 +85,7 @@ int transCommit() { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif #endif @@ -102,7 +108,7 @@ int transCommit() { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif #endif @@ -131,7 +137,7 @@ int transCommit() { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif #endif @@ -250,10 +256,12 @@ int transCommit() { #define NUMWRTOTAL numoidwrlocked #endif -#ifdef STMARRAY +#if defined(STMARRAY) #define STMARRAYFREE free(oidrdlockedarray); #define STMARRAYALLOC oidrdlockedarray=malloc(size); #define STMARRAYASSIGN oidrdlockedarray=rdlockedarray; + +//allocation statements for dirwrindex #define STMARRAYDELAYFREE free(dirwrindex); #define STMARRAYDELAYALLOC dirwrindex=malloc(t_numelements*sizeof(int)); #define STMARRAYDELAYASSIGN dirwrindex=wrindex; @@ -262,6 +270,15 @@ int transCommit() { void * rdlockedarray[200]; \ void ** oidrdlockedarray; +#define ABORT \ + transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked)); \ + freearrays; \ + if (softabort) \ + return TRANS_SOFT_ABORT; \ + else \ + return TRANS_ABORT; + + #define ARRAYABORT \ for(;j>=lowoffset;j--) { \ GETLOCKVAL(status, transao, j); \ @@ -270,19 +287,52 @@ int transCommit() { write_unlock(lockptr); \ } \ } \ - transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked)); \ - freearrays; \ - if (softabort) \ - return TRANS_SOFT_ABORT; \ - else \ - return TRANS_ABORT; - + ABORT + +#ifdef DUALVIEW +#define DVGETLOCK(x) \ + unsigned int * objlock=&(&((objheader_t *)x)[-1])->lock; \ + if(!rwread_trylock(objlock)) { \ + ABORT; \ + } + +//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) { \ + ABORT; \ + } \ + } +#else +#define DVGETLOCK(x) +#define DVCHECKLOCK(x) +#endif + +#if defined(DELAYCOMP)&&!defined(DUALVIEW) +#define READCHECK \ + else if (dc_t_chashSearchArray(mainao,j)) { \ + CFENCE; \ + unsigned int localversion; \ + unsigned int remoteversion; \ + GETVERSIONVAL(localversion, transao, j); \ + GETVERSIONVAL(remoteversion, mainao, j); \ + if (localversion != remoteversion) { \ + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); \ + freearrays; \ + return TRANS_ABORT; \ + } \ + } +#else +#define READCHECK +#endif #define PROCESSARRAY \ int type=((int *)cachedobj)[0]; \ if (type>=NUMCLASSES) { \ struct ArrayObject *transao=(struct ArrayObject *) cachedobj; \ struct ArrayObject *mainao=(struct ArrayObject *) objptr; \ + DVGETLOCK(mainao); \ int lowoffset=(transao->lowindex)>>INDEXSHIFT; \ int highoffset=(transao->highindex)>>INDEXSHIFT; \ int j; \ @@ -313,6 +363,7 @@ int transCommit() { } \ if (addwrobject) { \ dirwrlocked[numoidwrlocked++] = objptr; \ + DUALVIEWWRAP(transao->___objstatus___ |=DIRTY;) \ } \ if (addrdobject) { \ oidrdlockedarray[numoidrdlockedarray++]=objptr; \ @@ -323,6 +374,7 @@ int transCommit() { for(i=0; i___objlocation___; \ + DVCHECKLOCK(mainao); \ int lowoffset=(transao->lowindex)>>INDEXSHIFT; \ int highoffset=(transao->highindex)>>INDEXSHIFT; \ int j; \ @@ -342,7 +394,9 @@ int transCommit() { freearrays; \ return TRANS_ABORT; \ } \ - } else { \ + } \ + READCHECK \ + else { \ unsigned int localversion; \ unsigned int remoteversion; \ GETVERSIONVAL(localversion, transao, j); \ @@ -358,7 +412,7 @@ int transCommit() { } \ } \ } \ - } + } #else #define ARRAYDEFINES #define PROCESSARRAY @@ -372,7 +426,7 @@ int transCommit() { #endif #ifdef DELAYCOMP -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) #define ARRAYLOCK \ int intkey=dc_curr->intkey; \ if (intkey!=-1) { \ @@ -397,9 +451,37 @@ int transCommit() { } \ } \ } else + +#elif defined(STMARRAY)&&defined(DUALVIEW) +#define ARRAYLOCK \ + if (((struct ___Object___ *)objptr)->type>=NUMCLASSES) { \ + if (!rwwrite_trylock(&header->lock)) { \ + ARRAYDELAYWRAP(dirwrindex[numoidwrtotal]=0;); \ + dirwrlocked[numoidwrtotal++] = objptr; \ + } else { \ + chashlistnode_t *node = &c_table[(((unsigned INTPTR)objptr) & c_mask)>>4]; \ + do { \ + if(node->key == objptr) { \ + objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; \ + if(STATUS(headeraddr) & DIRTY) { \ + if (rwconvert_trylock(&header->lock)) { \ + ARRAYDELAYWRAP(dirwrindex[numoidwrtotal]=1;); \ + dirwrlocked[numoidwrtotal++] = objptr; \ + goto nextloop; \ + } \ + } \ + break; \ + } \ + node = node->next; \ + } while(node != NULL); \ + ABORT; \ + } \ + } else #else #define ARRAYLOCK #endif + + #define ACCESSLOCKS \ unsigned int numoidwrtotal=numoidwrlocked; \ dchashlistnode_t *dc_curr = dc_c_list; \ @@ -445,9 +527,6 @@ int transCommit() { #define ACCESSLOCKS #endif - - - /* ================================================== * traverseCache * - goes through the transaction cache and @@ -886,11 +965,15 @@ void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrlocked) { write_unlock(lockptr); } } +#ifdef DUALVIEW + //release object array lock + rwread_unlock(&header->lock); +#endif } else #endif write_unlock(&header->lock); } -#if defined(STMARRAY)&&defined(DELAYCOMP) +#if defined(STMARRAY)&&defined(DELAYCOMP)&&!defined(DUALVIEW) //release access locks for(i=numoidwrtotal-1; i>=numoidwrlocked; i--) { struct ___Object___ * dst=dirwrlocked[i]; @@ -898,18 +981,32 @@ void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrlocked) { int wrindex=dirwrindex[i]; if (wrindex==-1) { //normal object - header->version++; write_unlock(&header->lock); } else { //array element unsigned int *intptr; - GETVERSIONPTR(intptr, ((struct ArrayObject *)dst), wrindex); - (*intptr)++; GETLOCKPTR(intptr, ((struct ArrayObject *)dst), wrindex); write_unlock(intptr); } } #endif +#if defined(STMARRAY)&&defined(DELAYCOMP)&&defined(DUALVIEW) + //release access locks + for(i=numoidwrtotal-1; i>=numoidwrlocked; i--) { + struct ___Object___ * dst=dirwrlocked[i]; + header = &((objheader_t *)dst)[-1]; + int wrindex=dirwrindex[i]; + if (wrindex==-1) { + //normal object + write_unlock(&header->lock); + } else if (wrindex==0) { + //array element + rwwrite_unlock(&header->lock); + } else { + rwconvert_unlock(&header->lock); + } + } +#endif #ifdef STMSTATS /* clear trec and then release objects locked */ struct objlist *ptr=lockedobjs; @@ -989,14 +1086,15 @@ void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { ptrstack.maxcount=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.maxcount=0; #endif //splice oidwrlocked in oidwrlocked->size=numoidwrtotal; oidwrlocked->next=params; ((struct garbagelist *)locals)->next=oidwrlocked; - commitmethod(params, locals, primitives); + if (commitmethod!=NULL) + commitmethod(params, locals, primitives); ((struct garbagelist *)locals)->next=params; #endif @@ -1028,6 +1126,9 @@ void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { write_unlock(intptr); } } +#ifdef DUALVIEW + rwread_unlock(&header->lock); +#endif } else #endif { @@ -1035,7 +1136,25 @@ void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { write_unlock(&header->lock); } } -#if defined(STMARRAY)&&defined(DELAYCOMP) +#if defined(STMARRAY)&&defined(DELAYCOMP)&&defined(DUALVIEW) + //release access locks + for(i=numoidwrtotal-1; i>=numoidwrlocked; i--) { + struct ___Object___ * dst=dirwrlocked[i]; + int wrlock=dirwrindex[i]; + header = &((objheader_t *)dst)[-1]; + if (wrlock==-1) { + //problem...what if we are double locked + header->version++; + write_unlock(&header->lock); + } else if (wrlock==0) { + rwwrite_unlock(&header->lock); + } else { + //normal object + rwconvert_unlock(&header->lock); + } + } +#endif +#if defined(STMARRAY)&&defined(DELAYCOMP)&&!defined(DUALVIEW) //release access locks for(i=numoidwrtotal-1; i>=numoidwrlocked; i--) { struct ___Object___ * dst=dirwrlocked[i]; @@ -1069,4 +1188,3 @@ void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { } #endif } - diff --git a/Robust/src/Runtime/STM/delaycomp.h b/Robust/src/Runtime/STM/delaycomp.h index 3cfd6413..4f5d9588 100644 --- a/Robust/src/Runtime/STM/delaycomp.h +++ b/Robust/src/Runtime/STM/delaycomp.h @@ -31,7 +31,7 @@ struct branchlist { extern __thread struct pointerlist ptrstack; extern __thread struct primitivelist primstack; extern __thread struct branchlist branchstack; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) struct arraylist { int count; void * prev; diff --git a/Robust/src/Runtime/STM/sandbox.c b/Robust/src/Runtime/STM/sandbox.c index c3d9ccf3..e504b83a 100644 --- a/Robust/src/Runtime/STM/sandbox.c +++ b/Robust/src/Runtime/STM/sandbox.c @@ -29,7 +29,7 @@ void checkObjects() { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif #endif @@ -56,7 +56,7 @@ void CALL11(___System______Assert____Z, int ___status___, int ___status___) { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif #endif @@ -90,7 +90,7 @@ void errorhandler(int sig, struct sigcontext ctx) { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif #endif diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index e8a8aaab..fb37e3f2 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -27,7 +27,7 @@ __thread struct objlist * newobjs; __thread struct pointerlist ptrstack; __thread struct primitivelist primstack; __thread struct branchlist branchstack; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) __thread struct arraylist arraystack; #endif #endif @@ -93,7 +93,15 @@ objheader_t *transCreateObj(void * ptr, unsigned int size) { objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size)); #endif objheader_t *retval=tmp+1; +#ifdef DUALVIEW + if (bytelength==0) { + tmp->lock=SWAP_LOCK_BIAS; + } else { + tmp->lock=RW_LOCK_BIAS; + } +#else tmp->lock=SWAP_LOCK_BIAS; +#endif tmp->version = 1; //initialize obj lock to the header STATUS(tmp)=NEW; diff --git a/Robust/src/Runtime/STM/stmlock.h b/Robust/src/Runtime/STM/stmlock.h index fda20455..19230fe4 100644 --- a/Robust/src/Runtime/STM/stmlock.h +++ b/Robust/src/Runtime/STM/stmlock.h @@ -52,6 +52,11 @@ static inline void rwwrite_unlock(volatile unsigned int *rw) { : "+m" (*rw) : "i" (RW_LOCK_BIAS) : "memory"); } +static inline void rwconvert_unlock(volatile unsigned int *rw) { + __asm__ __volatile__ (LOCK_PREFIX "addl %1, %0" + : "+m" (*rw) : "i" (RW_LOCK_BIAS-1) : "memory"); +} + static inline void atomic_dec(volatile unsigned int *v) { __asm__ __volatile__ (LOCK_PREFIX "decl %0" : "+m" (*v)); @@ -88,4 +93,12 @@ static inline int rwwrite_trylock(volatile unsigned int *lock) { atomic_add(RW_LOCK_BIAS, lock); return 0; // failed to acquire a write lock } + +static inline int rwconvert_trylock(volatile unsigned int *lock) { + if (atomic_sub_and_test((RW_LOCK_BIAS-1), lock)) { + return 1; // get a write lock + } + atomic_add((RW_LOCK_BIAS-1), lock); + return 0; // failed to acquire a write lock +} #endif diff --git a/Robust/src/Runtime/STM/stmlookup.c b/Robust/src/Runtime/STM/stmlookup.c index 77277f78..97131b30 100644 --- a/Robust/src/Runtime/STM/stmlookup.c +++ b/Robust/src/Runtime/STM/stmlookup.c @@ -275,7 +275,7 @@ void dc_t_chashInsertOnce(void * key, void *val) { if(ptr->key==0) { ptr->key=key; ptr->val=val; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) ptr->intkey=-1; #endif ptr->lnext=dc_c_list; @@ -305,7 +305,7 @@ void dc_t_chashInsertOnce(void * key, void *val) { node=&tcl->array[0]; tcl->num=1; } -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) node->intkey=-1; #endif node->key = key; @@ -317,7 +317,7 @@ void dc_t_chashInsertOnce(void * key, void *val) { } } -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) //Store objects and their pointers into hash void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) { dchashlistnode_t *ptr; @@ -401,7 +401,7 @@ unsigned int dc_t_chashResize(unsigned int newsize) { isfirst = 1; do { //Inner loop to go through linked lists void * key; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) unsigned int intkey; #endif dchashlistnode_t *tmp,*next; @@ -409,7 +409,7 @@ unsigned int dc_t_chashResize(unsigned int newsize) { if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0 break; //key = val =0 for element if not present within the hash table } -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) intkey=curr->intkey; index = (((unsigned INTPTR)key^(intkey<<4)) & mask) >>4; #else @@ -420,7 +420,7 @@ unsigned int dc_t_chashResize(unsigned int newsize) { // Insert into the new table if(tmp->key == 0) { tmp->key = key; -#ifdef STMARRAY +#if defined(STMARRAY)&!defined(DUALVIEW) tmp->intkey = intkey; #endif tmp->val = curr->val; @@ -482,7 +482,7 @@ INLINE void * dc_t_chashSearch(void * key) { return NULL; } -#ifdef STMARRAY +#if defined(STMARRAY)&!defined(DUALVIEW) // Search for an address for a given oid INLINE void * dc_t_chashSearchArray(void * key, unsigned int intkey) { //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE diff --git a/Robust/src/Runtime/STM/stmlookup.h b/Robust/src/Runtime/STM/stmlookup.h index 2b83dde0..e2529287 100644 --- a/Robust/src/Runtime/STM/stmlookup.h +++ b/Robust/src/Runtime/STM/stmlookup.h @@ -93,7 +93,7 @@ void rd_t_chashreset(); typedef struct dchashlistnode { void * key; -#ifdef STMARRAY +#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 diff --git a/Robust/src/Runtime/STM/tm.h b/Robust/src/Runtime/STM/tm.h index 3690a42e..edfba6f7 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -189,7 +189,7 @@ void objstrReset(); void objstrDelete(objstr_t *store); objstr_t *objstrCreate(unsigned int size); void transStart(); -#ifdef STMARRAY +#if defined(STMARRAY) objheader_t *transCreateObj(void * ptr, unsigned int size, int bytelength); #else objheader_t *transCreateObj(void * ptr, unsigned int size); @@ -204,7 +204,7 @@ __attribute__((pure)) void *transReadOnly(void *); 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); -#ifdef STMARRAY +#if defined(STMARRAY) void transCommitProcess(struct garbagelist *, int *, int, int, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params); #else void transCommitProcess(struct garbagelist *, int, int, 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 55135b17..7255a357 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -30,7 +30,7 @@ #define NUMPTRS 100 -#define INITIALHEAPSIZE 256*1024*1024L +#define INITIALHEAPSIZE 512*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 @@ -207,7 +207,8 @@ void fixtable(chashlistnode_t ** tc_table, chashlistnode_t **tc_list, cliststruc int j; for(j=lowindex; j<=highindex; j++) { unsigned int lockval; - if (GETLOCKVAL(lockval, ao, j)==STMDIRY) { + GETLOCKVAL(lockval, ao, j); + if (lockval==STMDIRTY) { int lowi=(j<lockedlist); #endif } +#endif +#if defined(STM)||defined(THREADS) *(listptr->base)=NULL; #endif stackptr=listptr->stackptr; @@ -661,7 +667,7 @@ void stopforgc(struct garbagelist * ptr) { //just append us to the list ptrstack.prev=ptr; ptr=(struct garbagelist *) &ptrstack; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.prev=ptr; ptr=(struct garbagelist *) &arraystack; #endif @@ -671,6 +677,9 @@ void stopforgc(struct garbagelist * ptr) { #ifdef THREADS litem.locklist=pthread_getspecific(threadlocks); #endif +#if defined(STM)||defined(THREADS) + litem.base=&memorybase; +#endif #ifdef STM litem.tc_size=c_size; litem.tc_table=&c_table; @@ -680,7 +689,6 @@ void stopforgc(struct garbagelist * ptr) { #ifdef STMSTATS litem.lockedlist=lockedobjs; #endif - litem.base=&memorybase; #endif #else //handle MAC diff --git a/Robust/src/Runtime/garbage.h b/Robust/src/Runtime/garbage.h index f3428c2e..0a923747 100644 --- a/Robust/src/Runtime/garbage.h +++ b/Robust/src/Runtime/garbage.h @@ -25,6 +25,8 @@ struct listitem { #ifdef STMSTATS struct objlist * lockedlist; #endif +#endif +#if defined(THREADS)||defined(STM) char **base; #endif }; diff --git a/Robust/src/Runtime/runtime.c b/Robust/src/Runtime/runtime.c index 245fe9f3..0eacaa6f 100644 --- a/Robust/src/Runtime/runtime.c +++ b/Robust/src/Runtime/runtime.c @@ -173,6 +173,9 @@ int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, doub void deepArrayCopy(struct ___Object___ * dst, struct ___Object___ * src) { int dsttype=((int *)dst)[0]; int srctype=((int *)src)[0]; +#ifdef STMARRAY + src=src->___objlocation___; +#endif if (dsttypelock=RW_LOCK_BIAS; +#else initdsmlocks(&tmp->lock); +#endif tmp->version=1; v->type=type; if (length<0) { diff --git a/Robust/src/Runtime/thread.c b/Robust/src/Runtime/thread.c index 47704013..02561d59 100644 --- a/Robust/src/Runtime/thread.c +++ b/Robust/src/Runtime/thread.c @@ -199,7 +199,7 @@ void initializethreads() { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif int a=mprotect((downpage(&ptrstack.buffer[1024])), 4096, PROT_NONE); @@ -211,7 +211,7 @@ void initializethreads() { a=mprotect(downpage(&branchstack.array[MAXBRANCHES]), 4096, PROT_NONE); if (a==-1) perror("branchstack"); -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) a=mprotect(downpage(&arraystack.index[MAXARRAY]), 4096, PROT_NONE); if (a==-1) perror("arraystack"); @@ -300,7 +300,7 @@ void initthread(struct ___Thread___ * ___this___) { ptrstack.count=0; primstack.count=0; branchstack.count=0; -#ifdef STMARRAY +#if defined(STMARRAY)&&!defined(DUALVIEW) arraystack.count=0; #endif int a=mprotect(downpage(&ptrstack.buffer[1024]), 4096, PROT_NONE); @@ -312,7 +312,7 @@ void initthread(struct ___Thread___ * ___this___) { a=mprotect(downpage(&branchstack.array[MAXBRANCHES]), 4096, PROT_NONE); if (a==-1) perror("branchstack"); -#ifdef STMARRAY +#if defined(STMARRAY)&!defined(DUALVIEW) a=mprotect(downpage(&arraystack.index[MAXARRAY]), 4096, PROT_NONE); if (a==-1) perror("arraystack"); diff --git a/Robust/src/Runtime/thread.h b/Robust/src/Runtime/thread.h index d2f80dfa..4f65bd68 100644 --- a/Robust/src/Runtime/thread.h +++ b/Robust/src/Runtime/thread.h @@ -12,6 +12,19 @@ extern pthread_cond_t objcond; extern pthread_key_t threadlocks; extern pthread_mutex_t atomiclock; +#ifdef PRECISE_GC +#define ATOMICLOCK if (pthread_mutex_trylock(&atomiclock)!=0) { \ + stopforgc((struct garbagelist *) &___locals___); \ + pthread_mutex_lock(&atomiclock); \ + restartaftergc(); \ + } + +#define ATOMICUNLOCK pthread_mutex_unlock(&atomiclock) +#else +#define ATOMICLOCK pthread_mutex_lock(&atomiclock) +#define ATOMICUNLOCK pthread_mutex_unlock(&atomiclock) +#endif + #if defined(THREADS)||defined(STM) void initthread(struct ___Thread___ * ___this___); #endif