this.gft=gft;
this.notreadymap=new Hashtable<LocalityBinding, HashSet<FlatNode>>();
this.cannotdelaymap=new Hashtable<LocalityBinding, HashSet<FlatNode>>();
- if (state.STMARRAY)
+ if (state.STMARRAY&&!state.DUALVIEW)
this.derefmap=new Hashtable<LocalityBinding, HashSet<FlatNode>>();
this.othermap=new Hashtable<LocalityBinding, HashSet<FlatNode>>();
}
HashSet<FlatNode> delayedset=notreadymap.get(lb);
HashSet<FlatNode> derefset=null;
- if (state.STMARRAY)
+ if (state.STMARRAY&&!state.DUALVIEW)
derefset=derefmap.get(lb);
HashSet<FlatNode> otherset=othermap.get(lb);
HashSet<FlatNode> cannotdelayset=cannotdelaymap.get(lb);
}
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
Set<FlatNode> branchset=revbranchmap.get((FlatCondBranch)fn);
for(Iterator<FlatNode> 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;
}
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);
}
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);
}
}//end of while loop
if (lb.getHasAtomic()) {
- if (state.STMARRAY)
+ if (state.STMARRAY&&!state.DUALVIEW)
derefmap.put(lb, derefset);
cannotdelaymap.put(lb, cannotdelay);
}
}
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<FlatNode, Hashtable<TempDescriptor, Set<TempFlatPair>>> getMap(LocalityBinding lb) {
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);
}
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) {
outclassdefs.println(" int lowindex;");
outclassdefs.println(" int highindex;");
}
-
if (state.ARRAYPAD)
outclassdefs.println(" int paddingforarray;");
//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();
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+");");
}
}
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+");");
}
}
if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
storeset=delaycomp.livecode(lb);
genset=new HashSet<FlatNode>();
- if (state.STMARRAY) {
+ if (state.STMARRAY&&!state.DUALVIEW) {
refset=new HashSet<FlatNode>();
refset.addAll(delaycomp.getDeref(lb));
refset.removeAll(delaycomp.getCannotDelay(lb));
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<FlatNode>();
unionset.addAll(storeset);
unionset.addAll(genset);
- if (state.STMARRAY)
+ if (state.STMARRAY&&!state.DUALVIEW)
unionset.addAll(refset);
}
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);
}
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 {
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) {
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)) {
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
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;
}
}
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 SANDBOX=false;
public boolean DCOPTS=false;
public boolean DELAYCOMP=false;
+ public boolean DUALVIEW=false;
//Other options
public int CORENUM = 1;
public String structfile;
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;
/* 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)
#define LOWMASK (INDEXLENGTH-1) //mast off low order bits
#define HIGHMASK ~(LOWMASK) //mask off high order bits
((type *)(((char *) lengthoff)+sizeof(int)))[index]=src; \
}
#endif
+
+#define VERSIONINCREMENT(array, index, type) { \
+ unsigned int * versionptr; \
+ GETVERSIONPTR(versionptr, array,((sizeof(type)*index)>>INDEXSHIFT)); \
+ (*versionptr)++; \
+}
#define ARRAYDELAYWRAP1(x)
#endif
+#ifdef DUALVIEW
+#define DUALVIEWWRAP(x) x
+#else
+#define DUALVIEWWRAP(x)
+#endif
+
/* ================================================================
* transCommit
* - This function initiates the transaction commit process
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
#endif
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
#endif
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
#endif
#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;
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); \
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; \
} \
if (addwrobject) { \
dirwrlocked[numoidwrlocked++] = objptr; \
+ DUALVIEWWRAP(transao->___objstatus___ |=DIRTY;) \
} \
if (addrdobject) { \
oidrdlockedarray[numoidrdlockedarray++]=objptr; \
for(i=0; i<numoidrdlockedarray; i++) { \
struct ArrayObject * transao=(struct ArrayObject *) oidrdlockedarray[i]; \
struct ArrayObject * mainao=(struct ArrayObject *) transao->___objlocation___; \
+ DVCHECKLOCK(mainao); \
int lowoffset=(transao->lowindex)>>INDEXSHIFT; \
int highoffset=(transao->highindex)>>INDEXSHIFT; \
int j; \
freearrays; \
return TRANS_ABORT; \
} \
- } else { \
+ } \
+ READCHECK \
+ else { \
unsigned int localversion; \
unsigned int remoteversion; \
GETVERSIONVAL(localversion, transao, j); \
} \
} \
} \
- }
+ }
#else
#define ARRAYDEFINES
#define PROCESSARRAY
#endif
#ifdef DELAYCOMP
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
#define ARRAYLOCK \
int intkey=dc_curr->intkey; \
if (intkey!=-1) { \
} \
} \
} 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; \
#define ACCESSLOCKS
#endif
-
-
-
/* ==================================================
* traverseCache
* - goes through the transaction cache and
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];
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;
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
write_unlock(intptr);
}
}
+#ifdef DUALVIEW
+ 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];
+ 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];
}
#endif
}
-
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;
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
#endif
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
#endif
ptrstack.count=0;
primstack.count=0;
branchstack.count=0;
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
#endif
__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
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;
: "+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));
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
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;
node=&tcl->array[0];
tcl->num=1;
}
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
node->intkey=-1;
#endif
node->key = key;
}
}
-#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;
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;
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
// 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;
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
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
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);
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);
#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
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<<INDEXSHIFT)/sizeof(void *);
int highi=lowi+(INDEXLENGTH/sizeof(void *));
for(i=lowi; i<highi;i++) {
}
#ifdef STMARRAY
}
+ }
#endif
} else {
INTPTR size=pointer[0];
#ifdef DELAYCOMP
ptrstack.prev=stackptr;
stackptr=(struct garbagelist *) &ptrstack;
-#ifdef STMARRAY
+#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.prev=stackptr;
stackptr=(struct garbagelist *) &arraystack;
#endif
fixobjlist(lockedobjs);
#endif
}
+#endif
+#if defined(STM)||defined(THREADS)
memorybase=NULL;
#endif
fixobjlist(listptr->lockedlist);
#endif
}
+#endif
+#if defined(STM)||defined(THREADS)
*(listptr->base)=NULL;
#endif
stackptr=listptr->stackptr;
//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
#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;
#ifdef STMSTATS
litem.lockedlist=lockedobjs;
#endif
- litem.base=&memorybase;
#endif
#else
//handle MAC
#ifdef STMSTATS
struct objlist * lockedlist;
#endif
+#endif
+#if defined(THREADS)||defined(STM)
char **base;
#endif
};
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 (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
return;
struct ArrayObject *aodst=(struct ArrayObject *)dst;
objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
#endif
+#ifdef DUALVIEW
+ tmp->lock=RW_LOCK_BIAS;
+#else
initdsmlocks(&tmp->lock);
+#endif
tmp->version=1;
v->type=type;
if (length<0) {
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);
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");
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);
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");
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