From 7862aa9e5dacfbb0f33ef84e6ec7482de295c859 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Sat, 24 Oct 2009 01:25:38 +0000 Subject: [PATCH] get Fission w/ array support working --- Robust/src/IR/Flat/BuildCode.java | 30 +-- Robust/src/Runtime/STM/array.h | 2 +- Robust/src/Runtime/STM/commit.c | 377 +++++++++++++++++------------ Robust/src/Runtime/STM/delaycomp.h | 4 +- Robust/src/Runtime/STM/stmlookup.c | 17 +- Robust/src/Runtime/STM/stmlookup.h | 2 + Robust/src/Runtime/STM/tm.h | 12 +- 7 files changed, 265 insertions(+), 179 deletions(-) diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index cb9e3642..240fb7f1 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -2357,15 +2357,15 @@ public class BuildCode { String dst=generateTemp(fm, fsen.getDst(), lb); String src=generateTemp(fm, fsen.getSrc(), lb); String index=generateTemp(fm, fsen.getIndex(), lb); + TypeDescriptor elementtype=fsen.getDst().getType().dereference(); + String type=""; + if (elementtype.isArray()||elementtype.isClass()) + type="void *"; + else + type=elementtype.getSafeSymbol()+" "; if (firstpass) { - output.println("STOREARRAY("+dst+","+index+")"); + output.println("STOREARRAY("+dst+","+index+","+type+")"); } else { - TypeDescriptor elementtype=fsen.getDst().getType().dereference(); - String type=""; - if (elementtype.isArray()||elementtype.isClass()) - type="void *"; - else - type=elementtype.getSafeSymbol()+" "; output.println("{"); output.println(" struct ArrayObject *array;"); output.println(" int index;"); @@ -2377,16 +2377,16 @@ public class BuildCode { FlatElementNode fen=(FlatElementNode) fn; String src=generateTemp(fm, fen.getSrc(), lb); String index=generateTemp(fm, fen.getIndex(), lb); + TypeDescriptor elementtype=fen.getSrc().getType().dereference(); + String dst=generateTemp(fm, fen.getDst(), lb); + String type=""; + if (elementtype.isArray()||elementtype.isClass()) + type="void *"; + else + type=elementtype.getSafeSymbol()+" "; if (firstpass) { - output.println("STOREARRAY("+src+","+index+");"); + output.println("STOREARRAY("+src+","+index+","+type+");"); } else { - TypeDescriptor elementtype=fen.getSrc().getType().dereference(); - String dst=generateTemp(fm, fen.getDst(), lb); - String type=""; - if (elementtype.isArray()||elementtype.isClass()) - type="void *"; - else - type=elementtype.getSafeSymbol()+" "; output.println("{"); output.println(" struct ArrayObject *array;"); output.println(" int index;"); diff --git a/Robust/src/Runtime/STM/array.h b/Robust/src/Runtime/STM/array.h index 33b9fa64..7a31bb87 100644 --- a/Robust/src/Runtime/STM/array.h +++ b/Robust/src/Runtime/STM/array.h @@ -2,7 +2,7 @@ #define ARRAY_H /* Array layout */ -#define INDEXSHIFT 4 //must be at least 3 for doubles +#define INDEXSHIFT 5 //must be at least 3 for doubles //#define DBLINDEXSHIFT INDEXSHIFT-1 //must be at least 3 for doubles #define INDEXLENGTH (1<=200) { \ free(oidwrlocked); \ + STMARRAYDELAYFREE; \ } #else #define freearrays if (c_numelements>=200) { \ @@ -156,71 +166,73 @@ int transCommit() { #endif #ifdef DELAYCOMP -#define allocarrays int t_numelements=c_numelements+dc_c_numelements; \ - if (t_numelements<200) { \ +#define allocarrays int t_numelements=c_numelements+dc_c_numelements; \ + if (t_numelements<200) { \ oidwrlocked=(struct garbagelist *) &wrlocked; \ - } else { \ - oidwrlocked=malloc(2*sizeof(INTPTR)+t_numelements*sizeof(void *)); \ - } \ - if (c_numelements<200) { \ - oidrdlocked=rdlocked; \ - oidrdversion=rdversion; \ - STATASSIGN; \ - STMARRAYASSIGN; \ - } else { \ - int size=c_numelements*sizeof(void*); \ - oidrdlocked=malloc(size); \ - oidrdversion=malloc(size); \ - STATALLOC; \ - STMARRAYALLOC; \ - }\ + STMARRAYDELAYASSIGN; \ + } else { \ + oidwrlocked=malloc(2*sizeof(INTPTR)+t_numelements*(sizeof(void *))); \ + STMARRAYDELAYALLOC; \ + } \ + if (c_numelements<200) { \ + oidrdlocked=rdlocked; \ + oidrdversion=rdversion; \ + STATASSIGN; \ + STMARRAYASSIGN; \ + } else { \ + int size=c_numelements*sizeof(void*); \ + oidrdlocked=malloc(size); \ + oidrdversion=malloc(size); \ + STATALLOC; \ + STMARRAYALLOC; \ + } \ dirwrlocked=oidwrlocked->array; #else -#define allocarrays if (c_numelements<200) { \ - oidrdlocked=rdlocked; \ - oidrdversion=rdversion; \ +#define allocarrays if (c_numelements<200) { \ + oidrdlocked=rdlocked; \ + oidrdversion=rdversion; \ oidwrlocked=(struct garbagelist *) &wrlocked; \ STATASSIGN; \ STMARRAYASSIGN; \ - } else { \ - int size=c_numelements*sizeof(void*); \ - oidrdlocked=malloc(size); \ - oidrdversion=malloc(size); \ - oidwrlocked=malloc(size+2*sizeof(INTPTR)); \ - STATALLOC; \ - STMARRAYALLOC; \ - } \ + } else { \ + int size=c_numelements*sizeof(void*); \ + oidrdlocked=malloc(size); \ + oidrdversion=malloc(size); \ + oidwrlocked=malloc(size+2*sizeof(INTPTR)); \ + STATALLOC; \ + STMARRAYALLOC; \ + } \ dirwrlocked=oidwrlocked->array; #endif #ifdef STMSTATS -#define ABORTSTAT1 header->abortCount++; \ - ObjSeqId = headeraddr->accessCount; \ +#define ABORTSTAT1 header->abortCount++; \ + ObjSeqId = headeraddr->accessCount; \ (typesCausingAbort[TYPE(header)]).numabort++; \ (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \ (typesCausingAbort[TYPE(header)]).numtrans+=1; \ objtypetraverse[TYPE(header)]=1; \ if(getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) \ softabort=0; -#define ABORTSTAT2 \ - ObjSeqId = oidrdage[i];\ - header->abortCount++; \ - (typesCausingAbort[TYPE(header)]).numabort++; \ - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \ - (typesCausingAbort[TYPE(header)]).numtrans+=1; \ +#define ABORTSTAT2 \ + ObjSeqId = oidrdage[i]; \ + header->abortCount++; \ + (typesCausingAbort[TYPE(header)]).numabort++; \ + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \ + (typesCausingAbort[TYPE(header)]).numtrans+=1; \ objtypetraverse[TYPE(header)]=1; \ if (getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) \ softabort=0; -#define ABORTSTAT3 \ - header->abortCount++; \ - ObjSeqId = headeraddr->accessCount; \ - (typesCausingAbort[TYPE(header)]).numabort++; \ - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \ - (typesCausingAbort[TYPE(header)]).numtrans+=1; \ +#define ABORTSTAT3 \ + header->abortCount++; \ + ObjSeqId = headeraddr->accessCount; \ + (typesCausingAbort[TYPE(header)]).numabort++; \ + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; \ + (typesCausingAbort[TYPE(header)]).numtrans+=1; \ objtypetraverse[TYPE(header)]=1; \ if (getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) \ softabort=0; -#define ABORTSTAT4 ObjSeqId = oidrdage[i]; \ +#define ABORTSTAT4 ObjSeqId = oidrdage[i]; \ header->abortCount++; \ getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); #else @@ -242,6 +254,9 @@ int transCommit() { #define STMARRAYFREE free(oidrdlockedarray); #define STMARRAYALLOC oidrdlockedarray=malloc(size); #define STMARRAYASSIGN oidrdlockedarray=rdlockedarray; +#define STMARRAYDELAYFREE free(dirwrindex); +#define STMARRAYDELAYALLOC dirwrindex=malloc(t_numelements*sizeof(int)); +#define STMARRAYDELAYASSIGN dirwrindex=wrindex; #define ARRAYDEFINES int numoidrdlockedarray=0; \ void * rdlockedarray[200]; \ @@ -255,7 +270,7 @@ int transCommit() { write_unlock(lockptr); \ } \ } \ - transAbortProcess(oidwrlocked, numoidwrlocked); \ + transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked)); \ freearrays; \ if (softabort) \ return TRANS_SOFT_ABORT; \ @@ -278,12 +293,12 @@ int transCommit() { if (status==STMDIRTY) { \ unsigned int * lockptr; \ GETLOCKPTR(lockptr, mainao,j); \ - if (write_trylock(lockptr)) { \ + if (likely(write_trylock(lockptr))) { \ unsigned int localversion; \ unsigned int remoteversion; \ GETVERSIONVAL(localversion, transao, j); \ GETVERSIONVAL(remoteversion, mainao, j); \ - if (localversion == remoteversion) { \ + if (likely(localversion == remoteversion)) { \ addwrobject=1; \ } else { \ ARRAYABORT; \ @@ -323,7 +338,7 @@ int transCommit() { GETVERSIONVAL(localversion, transao, j); \ GETVERSIONVAL(remoteversion, mainao, j); \ if (localversion != remoteversion) { \ - transAbortProcess(oidwrlocked, NUMWRTOTAL); \ + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); \ freearrays; \ return TRANS_ABORT; \ } \ @@ -334,7 +349,7 @@ int transCommit() { GETVERSIONVAL(remoteversion, mainao, j); \ if (localversion==remoteversion) \ softabort=1; \ - transAbortProcess(oidwrlocked, NUMWRTOTAL); \ + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); \ freearrays; \ if (softabort) \ return TRANS_SOFT_ABORT; \ @@ -351,8 +366,88 @@ int transCommit() { #define STMARRAYFREE #define STMARRAYALLOC #define STMARRAYASSIGN +#define STMARRAYDELAYFREE +#define STMARRAYDELAYALLOC +#define STMARRAYDELAYASSIGN #endif +#ifdef DELAYCOMP +#ifdef STMARRAY +#define ARRAYLOCK \ + int intkey=dc_curr->intkey; \ + if (intkey!=-1) { \ + unsigned int *lockptr; \ + GETLOCKPTR(lockptr, objptr, intkey); \ + if (likely(write_trylock(lockptr))) { \ + /*have lock on element */ \ + 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; \ + } \ + } \ + } else +#else +#define ARRAYLOCK +#endif +#define ACCESSLOCKS \ + unsigned int numoidwrtotal=numoidwrlocked; \ + dchashlistnode_t *dc_curr = dc_c_list; \ + /* 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 \ + if(likely(write_trylock(&header->lock))) { /*can aquire write lock*/ \ + ARRAYDELAYWRAP(dirwrindex[numoidwrtotal]=-1;) \ + dirwrlocked[numoidwrtotal++] = objptr; \ + } else { \ + /* maybe we already have lock*/ \ + 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) { \ + goto nextloop; \ + } else \ + break; \ + } \ + node = node->next; \ + } while(node != NULL); \ + \ + /*have to abort to avoid deadlock */ \ + transAbortProcess(oidwrlocked, numoidwrtotal ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); \ + ABORTSTAT1; \ + freearrays; \ + if (softabort) \ + return TRANS_SOFT_ABORT; \ + else \ + return TRANS_ABORT; \ + } \ + nextloop: \ + dc_curr = dc_curr->lnext; \ + } +#else +#define ACCESSLOCKS +#endif + + + + /* ================================================== * traverseCache * - goes through the transaction cache and @@ -361,9 +456,9 @@ int transCommit() { */ #ifdef DELAYCOMP - int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { #else - int traverseCache() { +int traverseCache() { #endif /* Create info to keep track of objects that can be locked */ int numoidrdlocked=0; @@ -379,6 +474,10 @@ int transCommit() { STMWRAP(int rdage[200];int * oidrdage;int ObjSeqId;int objtypetraverse[TOTALNUMCLASSANDARRAY];); struct garbagelist * oidwrlocked; void ** dirwrlocked; +#if defined(STMARRAY)&&defined(DELAYCOMP) + int wrindex[200]; + int * dirwrindex; +#endif allocarrays; STMWRAP(for(i=0; ilock)) { //can aquire write lock - if (version == header->version) { /* versions match */ + if(likely(write_trylock(&header->lock))) { //can aquire write lock + if (likely(version == header->version)) { /* versions match */ /* Keep track of objects locked */ dirwrlocked[numoidwrlocked++] = objptr; } else { dirwrlocked[numoidwrlocked++] = objptr; - transAbortProcess(oidwrlocked, numoidwrlocked); + transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT1; freearrays; if (softabort) @@ -422,7 +521,7 @@ int transCommit() { /* versions match */ softabort=1; } - transAbortProcess(oidwrlocked, numoidwrlocked); + transAbortProcess(oidwrlocked, numoidwrlocked ARRAYDELAYWRAP1(NULL) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT1; freearrays; if (softabort) @@ -440,51 +539,9 @@ int transCommit() { } } //end of for -#ifdef DELAYCOMP - //acquire access set locks - unsigned int numoidwrtotal=numoidwrlocked; - - dchashlistnode_t *dc_curr = dc_c_list; - /* 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 - objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1]; - void *objptr=dc_curr->key; - objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t)); - if(write_trylock(&header->lock)) { //can aquire write lock - dirwrlocked[numoidwrtotal++] = objptr; - } else { - //maybe we already have lock - void * key=dc_curr->key; - chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; - - do { - if(node->key == key) { - objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; - if(STATUS(headeraddr) & DIRTY) { - goto nextloop; - } else - break; - } - node = node->next; - } while(node != NULL); - - //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, numoidwrtotal); - ABORTSTAT1; - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - nextloop: - dc_curr = dc_curr->lnext; - } -#endif + ACCESSLOCKS; //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** - READARRAYS; for(i=0; ilock>0) { //not write locked CFENCE; if(version != header->version) { /* versions do not match */ - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT2; freearrays; return TRANS_ABORT; @@ -504,7 +561,7 @@ int transCommit() { //couldn't get lock because we already have it //check if it is the right version number if (version!=header->version) { - transAbortProcess(oidwrlocked, numoidwrtotal); + transAbortProcess(oidwrlocked, numoidwrtotal ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT2; freearrays; return TRANS_ABORT; @@ -515,7 +572,7 @@ int transCommit() { if(version == header->version) { softabort=1; } - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT2; freearrays; if (softabort) @@ -536,7 +593,7 @@ int transCommit() { if(header->lock>0) { //object is not locked if (version!=header->version) { //have to abort - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); STMWRAP((typesCausingAbort[TYPE(header)])++;); freearrays; if (softabort) @@ -574,7 +631,7 @@ int transCommit() { } } //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); STMWRAP((typesCausingAbort[TYPE(header)])++;); freearrays; if (softabort) @@ -589,7 +646,7 @@ int transCommit() { /* Decide the final response */ #ifdef DELAYCOMP - transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); + transCommitProcess(oidwrlocked ARRAYDELAYWRAP1(dirwrindex), numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); #else transCommitProcess(oidwrlocked, numoidwrlocked); #endif @@ -623,6 +680,10 @@ int alttraverseCache() { ARRAYDEFINES; struct garbagelist * oidwrlocked; void ** dirwrlocked; +#if defined(STMARRAY)&&defined(DELAYCOMP) + int wrindex[200]; + int * dirwrindex; +#endif allocarrays; STMWRAP(for(i=0; ilnext; } -#ifdef DELAYCOMP - //acquire other locks - unsigned int numoidwrtotal=numoidwrlocked; - dchashlistnode_t *dc_curr = dc_c_list; - /* 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 - objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1]; - void *objptr=dc_curr->key; - objheader_t *header=(objheader_t *)(((char *)objptr)-sizeof(objheader_t)); - if(write_trylock(&header->lock)) { //can aquire write lock - dirwrlocked[numoidwrtotal++] = objptr; - } else { - //maybe we already have lock - void * key=dc_curr->key; - chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; - - do { - if(node->key == key) { - objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; - if(STATUS(headeraddr) & DIRTY) { - goto nextloop; - } - } - node = node->next; - } while(node != NULL); - - //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, numoidwrtotal); - ABORTSTAT3; - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - nextloop: - dc_curr = dc_curr->lnext; - } -#endif + ACCESSLOCKS; //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** READARRAYS; @@ -723,7 +745,7 @@ int alttraverseCache() { if(header->lock>0) { CFENCE; if(version != header->version) { - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT2; freearrays; return TRANS_ABORT; @@ -733,7 +755,7 @@ int alttraverseCache() { //couldn't get lock because we already have it //check if it is the right version number if (version!=header->version) { - transAbortProcess(oidwrlocked, numoidwrtotal); + transAbortProcess(oidwrlocked, numoidwrtotal ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT4; freearrays; return TRANS_ABORT; @@ -743,7 +765,7 @@ int alttraverseCache() { if(version == header->version) { softabort=1; } - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); ABORTSTAT2; freearrays; if (softabort) @@ -764,7 +786,7 @@ int alttraverseCache() { if(header->lock>0) { //object is not locked if (version!=header->version) { //have to abort - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); STMWRAP((typesCausingAbort[TYPE(header)])++;); freearrays; if (softabort) @@ -801,7 +823,7 @@ int alttraverseCache() { } } //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, NUMWRTOTAL); + transAbortProcess(oidwrlocked, NUMWRTOTAL ARRAYDELAYWRAP1(dirwrindex) ARRAYDELAYWRAP1(numoidwrlocked)); STMWRAP((typesCausingAbort[TYPE(header)])++;); freearrays; if (softabort) @@ -816,7 +838,7 @@ int alttraverseCache() { /* Decide the final response */ #ifdef DELAYCOMP - transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); + transCommitProcess(oidwrlocked ARRAYDELAYWRAP1(dirwrindex), numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); #else transCommitProcess(oidwrlocked, numoidwrlocked); #endif @@ -831,8 +853,12 @@ int alttraverseCache() { */ int logflag=1; - + +#if defined(STMARRAY)&&defined(DELAYCOMP) +void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrtotal, int * dirwrindex, int numoidwrlocked) { +#else void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrlocked) { +#endif int i; objheader_t *header; /* Release read locks */ @@ -864,6 +890,26 @@ void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrlocked) { #endif write_unlock(&header->lock); } +#if defined(STMARRAY)&&defined(DELAYCOMP) + //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 + 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 #ifdef STMSTATS /* clear trec and then release objects locked */ struct objlist *ptr=lockedobjs; @@ -885,7 +931,7 @@ void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrlocked) { * ================================= */ #ifdef DELAYCOMP - void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked, int numoidwrtotal, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +void transCommitProcess(struct garbagelist * oidwrlocked ARRAYDELAYWRAP1(int * dirwrindex), int numoidwrlocked, int numoidwrtotal, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { #else void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { #endif @@ -955,7 +1001,11 @@ void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { #endif /* Release write locks */ +#if defined(STMARRAY)&&defined(DELAYCOMP) + for(i=numoidwrlocked-1; i>=0; i--) { +#else for(i=NUMWRTOTAL-1; i>=0; i--) { +#endif struct ___Object___ * dst=dirwrlocked[i]; header = &((objheader_t *)dst)[-1]; #ifdef STMARRAY @@ -985,7 +1035,26 @@ void transCommitProcess(struct garbagelist * oidwrlocked, int numoidwrlocked) { write_unlock(&header->lock); } } - +#if defined(STMARRAY)&&defined(DELAYCOMP) + //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 + 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 #ifdef STMSTATS /* clear trec and then release objects locked */ ptr=lockedobjs; diff --git a/Robust/src/Runtime/STM/delaycomp.h b/Robust/src/Runtime/STM/delaycomp.h index 11be68a9..3cfd6413 100644 --- a/Robust/src/Runtime/STM/delaycomp.h +++ b/Robust/src/Runtime/STM/delaycomp.h @@ -47,11 +47,11 @@ extern __thread struct arraylist arraystack; #define RESTOREARRAY(x,z) {x=arraystack.array[arraystack.maxcount];z=arraystack.index[arraystack.maxcount++];} -#define STOREARRAY(x,z) {void * y=COMPOID(x); arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z; dc_t_chashInsertOnceArray(y,y,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,y);} #define STOREARRAYNOLOCK(x,z) {void * y=COMPOID(x); arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z;} -#define STOREARRAYNOTRANS(x,z) {void * y=x; arraystack.array[arraystack.count]=y; arraystack.index[arraystack.count++]=z; dc_t_chashInsertOnceArray(y,y,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; } diff --git a/Robust/src/Runtime/STM/stmlookup.c b/Robust/src/Runtime/STM/stmlookup.c index 594e3aeb..77277f78 100644 --- a/Robust/src/Runtime/STM/stmlookup.c +++ b/Robust/src/Runtime/STM/stmlookup.c @@ -1,5 +1,6 @@ #include "stmlookup.h" #include "strings.h" +#include "tm.h" __thread chashlistnode_t *c_table; __thread chashlistnode_t *c_list; @@ -274,6 +275,9 @@ void dc_t_chashInsertOnce(void * key, void *val) { if(ptr->key==0) { ptr->key=key; ptr->val=val; +#ifdef STMARRAY + ptr->intkey=-1; +#endif ptr->lnext=dc_c_list; dc_c_list=ptr; dc_c_numelements++; @@ -301,6 +305,9 @@ void dc_t_chashInsertOnce(void * key, void *val) { node=&tcl->array[0]; tcl->num=1; } +#ifdef STMARRAY + node->intkey=-1; +#endif node->key = key; node->val = val; node->next = ptr->next; @@ -315,16 +322,16 @@ void dc_t_chashInsertOnce(void * key, void *val) { void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) { dchashlistnode_t *ptr; - if (key==NULL) + if (unlikely(key==NULL)) return; - if(dc_c_numelements > (dc_c_threshold)) { + if(unlikely(dc_c_numelements > dc_c_threshold)) { //Resize unsigned int newsize = dc_c_size << 1; dc_t_chashResize(newsize); } - ptr = &dc_c_table[(((unsigned INTPTR)key^intkey)&dc_c_mask)>>4]; + ptr = &dc_c_table[(((unsigned INTPTR)key^(intkey<<4))&dc_c_mask)>>4]; if(ptr->key==0) { ptr->key=key; @@ -346,7 +353,7 @@ void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) { } while(search != NULL); dc_c_numelements++; - if (dc_c_structs->numnumarray[dc_c_structs->num]; dc_c_structs->num++; } else { @@ -404,7 +411,7 @@ unsigned int dc_t_chashResize(unsigned int newsize) { } #ifdef STMARRAY intkey=curr->intkey; - index = (((unsigned INTPTR)key^intkey) & mask) >>4; + index = (((unsigned INTPTR)key^(intkey<<4)) & mask) >>4; #else index = (((unsigned INTPTR)key) & mask) >>4; #endif diff --git a/Robust/src/Runtime/STM/stmlookup.h b/Robust/src/Runtime/STM/stmlookup.h index 0d74e46f..2b83dde0 100644 --- a/Robust/src/Runtime/STM/stmlookup.h +++ b/Robust/src/Runtime/STM/stmlookup.h @@ -93,7 +93,9 @@ void rd_t_chashreset(); typedef struct dchashlistnode { void * key; +#ifdef STMARRAY 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; diff --git a/Robust/src/Runtime/STM/tm.h b/Robust/src/Runtime/STM/tm.h index 250c4246..3690a42e 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -204,7 +204,11 @@ __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 +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); +#endif #else int transCommit(); int traverseCache(); @@ -212,7 +216,11 @@ int alttraverseCache(); void transCommitProcess(struct garbagelist *, int); #endif int altalttraverseCache(); +#if defined(STMARRAY)&&defined(DELAYCOMP) +void transAbortProcess(struct garbagelist *oidwrlocked, int numoidwrtotal, int * dirwrindex, int numoidwrlocked); +#else void transAbortProcess(struct garbagelist *, int); +#endif void randomdelay(int); #if defined(STMSTATS)||defined(SOFTABORT) int getTotalAbortCount(int, int, void *, int, void*, int*, int*, int, objheader_t*, int*); @@ -252,8 +260,8 @@ extern __thread struct objlist * lockedobjs; extern __thread int t_objnumcount; #endif -#define likely(x) x -#define unlikely(x) x +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) extern void * curr_heapbase; extern void * curr_heapptr; -- 2.34.1