From: bdemsky Date: Tue, 23 Jun 2009 05:39:01 +0000 (+0000) Subject: changes X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4cb57502e3d2d3c32c351b6f7d2c169c5f89d08a;p=IRC.git changes --- diff --git a/Robust/src/Runtime/STM/delaycomp.h b/Robust/src/Runtime/STM/delaycomp.h index 5fd8bfc5..4676e852 100644 --- a/Robust/src/Runtime/STM/delaycomp.h +++ b/Robust/src/Runtime/STM/delaycomp.h @@ -26,7 +26,7 @@ extern __thread primitivelist primstack; #define RESTOREPTR(x) x=ptrstack.array[--ptrstack.count] -#define STOREPTR(x) ptrstack.array[ptrstack.count++]=x +#define STOREPTR(x) ptrstack.array[ptrstack.count++]=x; dc_t_chashInsertOnce(x); //Branches diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index f31cd104..1877b8be 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -291,15 +291,19 @@ void freelockedobjs() { * - a final response * ================================================================ */ +#ifdef DELAYCOMP +int transCommit(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else int transCommit() { +#endif int softaborted=0; do { /* Look through all the objects in the transaction hash table */ int finalResponse; if (c_numelements<(c_size>>3)) - finalResponse= alttraverseCache(); + finalResponse= alttraverseCache(commitmethod, primitives, locals, params); else - finalResponse= traverseCache(); + finalResponse= traverseCache(commitmethod, primitives, locals, params); if(finalResponse == TRANS_ABORT) { #ifdef TRANSSTATS numTransAbort++; @@ -358,13 +362,32 @@ int transCommit() { } while (1); } +#ifdef DELAYCOMP +#define freearrays if (c_numelements>=200) { \ + free(oidrdlocked); \ + free(oidrdversion); \ + } \ + if (t_numelements>=200) { \ + free(oidwrlocked); \ + } +#else +#define freearrays if (c_numelements>=200) { \ + free(oidrdlocked); \ + free(oidrdversion); \ + free(oidwrlocked); \ + } +#endif /* ================================================== * traverseCache * - goes through the transaction cache and * - decides if a transaction should commit or abort * ================================================== */ +#ifdef DELAYCOMP +int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else int traverseCache() { +#endif /* Create info to keep track of objects that can be locked */ int numoidrdlocked=0; int numoidwrlocked=0; @@ -376,6 +399,22 @@ int traverseCache() { void ** oidrdlocked; void ** oidwrlocked; int * oidrdversion; +#ifdef DELAYCOMP + int t_numelements=c_numelements+dc_c_numelements; + if (t_numelements<200) { + oidwrlocked=wrlocked; + } else { + oidwrlocked=malloc(t_numelements*sizeof(void *)); + } + if (c_numelements<200) { + oidrdlocked=rdlocked; + oidrdversion=rdversion; + } else { + int size=c_numelements*sizeof(void*); + oidrdlocked=malloc(size); + oidrdversion=malloc(size); + } +#else if (c_numelements<200) { oidrdlocked=rdlocked; oidrdversion=rdversion; @@ -386,6 +425,7 @@ int traverseCache() { oidrdversion=malloc(size); oidwrlocked=malloc(size); } +#endif chashlistnode_t *ptr = c_table; /* Represents number of bins in the chash table */ unsigned int size = c_size; @@ -416,11 +456,7 @@ int traverseCache() { #endif DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; if (softabort) return TRANS_SOFT_ABORT; else @@ -442,11 +478,7 @@ int traverseCache() { #endif DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; if (softabort) return TRANS_SOFT_ABORT; else @@ -460,6 +492,50 @@ int traverseCache() { } } //end of for +#ifdef DELAYCOMP + //acquire other locks + chashlistnode_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]; + objheader_t *header=(objheader_t *)(((char *)dc_curr->key)-sizeof(objheader_t)); + if(write_trylock(&header->lock)) { //can aquire write lock + oidwrlocked[numoidwrlocked++] = header; + } else { + //maybe we already have lock + chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; + + do { + if(node->key == key) { + goto nextloop; + } + node = node->next; + } while(node != NULL); + + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrlocked); +#ifdef STMSTATS + ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if (getTotalAbortCount(i+1, size, (void *)(curr->next), NULL, 1)) + softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + nextloop: + dc_curr = dc_curr->lnext; + } +#endif + //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** for(i=0; iversion); DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; return TRANS_ABORT; } } else { /* cannot aquire lock */ @@ -500,11 +572,7 @@ int traverseCache() { #endif DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; if (softabort) return TRANS_SOFT_ABORT; else @@ -513,13 +581,13 @@ int traverseCache() { } /* Decide the final response */ +#ifdef DELAYCOMP + transCommitProcess(oidwrlocked, numoidwrlocked, commitmethod, primitives, locals, params); +#else transCommitProcess(oidwrlocked, numoidwrlocked); +#endif DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; return TRANS_COMMIT; } @@ -529,7 +597,12 @@ int traverseCache() { * - decides if a transaction should commit or abort * ================================================== */ + +#ifdef DELAYCOMP +int alttraverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else int alttraverseCache() { +#endif /* Create info to keep track of objects that can be locked */ int numoidrdlocked=0; int numoidwrlocked=0; @@ -541,6 +614,22 @@ int alttraverseCache() { void ** oidrdlocked; int * oidrdversion; void ** oidwrlocked; +#ifdef DELAYCOMP + int t_numelements=c_numelements+dc_c_numelements; + if (t_numelements<200) { + oidwrlocked=wrlocked; + } else { + oidwrlocked=malloc(t_numelements*sizeof(void *)); + } + if (c_numelements<200) { + oidrdlocked=rdlocked; + oidrdversion=rdversion; + } else { + int size=c_numelements*sizeof(void*); + oidrdlocked=malloc(size); + oidrdversion=malloc(size); + } +#else if (c_numelements<200) { oidrdlocked=rdlocked; oidrdversion=rdversion; @@ -551,6 +640,7 @@ int alttraverseCache() { oidrdversion=malloc(size); oidwrlocked=malloc(size); } +#endif chashlistnode_t *curr = c_list; /* Inner loop to traverse the linked list of the cache lookupTable */ while(likely(curr != NULL)) { @@ -575,11 +665,7 @@ int alttraverseCache() { #endif DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; return TRANS_ABORT; } } else { /* cannot aquire lock */ @@ -598,11 +684,7 @@ int alttraverseCache() { #endif DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; if (softabort) return TRANS_SOFT_ABORT; else @@ -616,6 +698,49 @@ int alttraverseCache() { curr = curr->lnext; } +#ifdef DELAYCOMP + //acquire other locks + chashlistnode_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]; + objheader_t *header=(objheader_t *)(((char *)dc_curr->key)-sizeof(objheader_t)); + if(write_trylock(&header->lock)) { //can aquire write lock + oidwrlocked[numoidwrlocked++] = header; + } else { + //maybe we already have lock + chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; + + do { + if(node->key == key) { + goto nextloop; + } + node = node->next; + } while(node != NULL); + + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrlocked); +#ifdef STMSTATS + ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if (getTotalAbortCount(i+1, size, (void *)(curr->next), NULL, 1)) + softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + nextloop: + dc_curr = dc_curr->lnext; + } +#endif //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** @@ -632,11 +757,7 @@ int alttraverseCache() { #endif DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; return TRANS_ABORT; } } else { /* cannot aquire lock */ @@ -654,11 +775,7 @@ int alttraverseCache() { #endif DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; if (softabort) return TRANS_SOFT_ABORT; else @@ -667,13 +784,13 @@ int alttraverseCache() { } /* Decide the final response */ +#ifdef DELAYCOMP + transCommitProcess(oidwrlocked, numoidwrlocked, commitmethod, primitives, locals, params); +#else transCommitProcess(oidwrlocked, numoidwrlocked); +#endif DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } + freearrays; return TRANS_COMMIT; } @@ -871,7 +988,11 @@ void transAbortProcess(void **oidwrlocked, int numoidwrlocked) { * * ================================= */ -void transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { +#ifdef DELAYCOMP + void transCommitProcess(void ** oidwrlocked, int numoidwrlocked, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else + void transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { +#endif objheader_t *header; void *ptrcreate; int i; @@ -901,6 +1022,11 @@ void transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { } __asm__ __volatile__("": : :"memory"); +#ifdef DELAYCOMP + // call commit method + commitmethod(primitives, locals, params); +#endif + /* Release write locks */ for(i=numoidwrlocked-1; i>=0; i--) { header = (objheader_t *)oidwrlocked[i]; diff --git a/Robust/src/Runtime/STM/stmlookup.c b/Robust/src/Runtime/STM/stmlookup.c index f770c779..40b8a9de 100644 --- a/Robust/src/Runtime/STM/stmlookup.c +++ b/Robust/src/Runtime/STM/stmlookup.c @@ -10,6 +10,196 @@ __thread unsigned int c_threshold; __thread double c_loadfactor; __thread cliststruct_t *c_structs; +#ifdef DELAYCOMP +__thread chashlistnode_t *dc_c_table; +__thread chashlistnode_t *dc_c_list; +__thread unsigned int dc_c_size; +__thread unsigned INTPTR dc_c_mask; +__thread unsigned int dc_c_numelements; +__thread unsigned int dc_c_threshold; +__thread double dc_c_loadfactor; +__thread cliststruct_t *dc_c_structs; + +void dc_t_chashCreate(unsigned int size, double loadfactor) { + chashtable_t *ctable; + chashlistnode_t *nodes; + int i; + + // Allocate space for the hash table + + dc_c_table = calloc(size, sizeof(chashlistnode_t)); + dc_c_loadfactor = loadfactor; + dc_c_size = size; + dc_c_threshold=size*loadfactor; + dc_c_mask = (size << 4)-1; + dc_c_structs=calloc(1, sizeof(cliststruct_t)); + dc_c_numelements = 0; // Initial number of elements in the hash + dc_c_list=NULL; +} + +void dc_t_chashreset() { + chashlistnode_t *ptr = dc_c_table; + int i; + + if (dc_c_numelements<(dc_c_size>>4)) { + chashlistnode_t *top=&ptr[dc_c_size]; + chashlistnode_t *tmpptr=dc_c_list; + while(tmpptr!=NULL) { + chashlistnode_t *next=tmpptr->lnext; + if (tmpptr>=ptr&&tmpptrkey=0; + tmpptr->next=NULL; + } + tmpptr=next; + } + } else { + bzero(dc_c_table, sizeof(chashlistnode_t)*dc_c_size); + } + while(dc_c_structs->next!=NULL) { + cliststruct_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; +} + +//Store objects and their pointers into hash +void dc_t_chashInsertOnce(void * key, void *val) { + chashlistnode_t *ptr; + + + if(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)&dc_c_mask)>>4]; + + if(ptr->key==0) { + ptr->key=key; + ptr->val=val; + ptr->lnext=dc_c_list; + dc_c_list=ptr; + dc_c_numelements++; + } else { // Insert in the beginning of linked list + chashlistnode_t * node; + chashlistnode_t *search=ptr; + + //make sure it isn't here + do { + if(search->key == key) { + return; + } + search=search->next; + } while(search != NULL); + + dc_c_numelements++; + if (dc_c_structs->numarray[dc_c_structs->num]; + dc_c_structs->num++; + } else { + //get new list + cliststruct_t *tcl=calloc(1,sizeof(cliststruct_t)); + tcl->next=dc_c_structs; + dc_c_structs=tcl; + node=&tcl->array[0]; + tcl->num=1; + } + node->key = key; + node->val = val; + node->next = ptr->next; + ptr->next=node; + node->lnext=dc_c_list; + dc_c_list=node; + } +} + +unsigned int dc_t_chashResize(unsigned int newsize) { + chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list + unsigned int oldsize; + int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable + unsigned int i,index; + unsigned int mask; + + ptr = dc_c_table; + oldsize = dc_c_size; + dc_c_list=NULL; + + if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return 1; + } + + dc_c_table = node; //Update the global hashtable upon resize() + dc_c_size = newsize; + dc_c_threshold = newsize * dc_c_loadfactor; + mask=dc_c_mask = (newsize << 4)-1; + + for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table + curr = &ptr[i]; + isfirst = 1; + do { //Inner loop to go through linked lists + void * key; + chashlistnode_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 + } + index = (((unsigned INTPTR)key) & mask) >>4; + tmp=&node[index]; + next = curr->next; + // Insert into the new table + if(tmp->key == 0) { + tmp->key = key; + tmp->val = curr->val; + tmp->lnext=dc_c_list; + dc_c_list=tmp; + } /* + NOTE: Add this case if you change this... + This case currently never happens because of the way things rehash.... + else if (isfirst) { + chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t)); + newnode->key = curr->key; + newnode->val = curr->val; + newnode->next = tmp->next; + tmp->next=newnode; + } */ + else { + curr->next=tmp->next; + tmp->next=curr; + curr->lnext=dc_c_list; + dc_c_list=curr; + } + + isfirst = 0; + curr = next; + } while(curr!=NULL); + } + + free(ptr); //Free the memory of the old hash table + return 0; +} + +//Delete the entire hash table +void dc_t_chashDelete() { + int i; + cliststruct_t *ptr=dc_c_structs; + while(ptr!=NULL) { + cliststruct_t *next=ptr->next; + free(ptr); + ptr=next; + } + free(dc_c_table); + dc_c_table=NULL; + dc_c_structs=NULL; + dc_c_list=NULL; +} +#endif + void t_chashCreate(unsigned int size, double loadfactor) { chashtable_t *ctable; chashlistnode_t *nodes; diff --git a/Robust/src/Runtime/STM/stmlookup.h b/Robust/src/Runtime/STM/stmlookup.h index c6af2e59..bdfe70f5 100644 --- a/Robust/src/Runtime/STM/stmlookup.h +++ b/Robust/src/Runtime/STM/stmlookup.h @@ -59,4 +59,13 @@ extern __thread unsigned int c_threshold; extern __thread double c_loadfactor; extern __thread cliststruct_t *c_structs; +#ifdef DELAYCOMP +void dc_t_chashCreate(unsigned int size, double loadfactor); +void dc_t_chashInsertOnce(void * key, void *val); +void * dc_t_chashSearch(void * key); +unsigned int dc_t_chashResize(unsigned int newsize); +void dc_t_chashDelete(); +void dc_t_chashreset(); +#endif + #endif diff --git a/Robust/src/Runtime/STM/tm.h b/Robust/src/Runtime/STM/tm.h index d82ecfd9..3d131777 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -169,12 +169,19 @@ objheader_t *transCreateObj(void * ptr, unsigned int size); unsigned int getNewOID(void); void *objstrAlloc(unsigned int size); __attribute__((pure)) void *transRead(void *, void *); +#ifdef DELAYCOMP +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); +void transCommitProcess(void **, int, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params); +#else int transCommit(); int traverseCache(); int alttraverseCache(); +void transCommitProcess(void **, int); +#endif int altalttraverseCache(); void transAbortProcess(void **, int); -void transCommitProcess(void **, int); void randomdelay(int); #if defined(STMSTATS)||defined(SOFTABORT) int getTotalAbortCount(int, int, void *, void *, int);