From 4960727034b5c0f3f505c921ee83190949ee9e24 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Mon, 13 Jul 2009 00:37:07 +0000 Subject: [PATCH] runtime support for read only TRANSREADS --- Robust/src/Main/Main.java | 2 + Robust/src/Runtime/DSTM/interface/queue.c | 8 +- Robust/src/Runtime/STM/stm.c | 304 +++++++++++++++++----- Robust/src/Runtime/STM/stmlock.c | 2 + Robust/src/Runtime/STM/stmlock.h | 5 +- Robust/src/Runtime/STM/stmlookup.c | 195 +++++++++++++- Robust/src/Runtime/STM/stmlookup.h | 35 ++- Robust/src/Runtime/STM/tm.h | 18 +- Robust/src/Runtime/garbage.c | 12 +- Robust/src/Runtime/thread.c | 6 + 10 files changed, 506 insertions(+), 81 deletions(-) diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index 270d4f90..5f18a514 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -157,6 +157,8 @@ public class Main { state.DSM=true; else if (option.equals("-singleTM")) state.SINGLETM=true; + else if (option.equals("-readset")) + state.READSET=true; else if (option.equals("-webinterface")) state.WEBINTERFACE=true; else if (option.equals("-instructionfailures")) diff --git a/Robust/src/Runtime/DSTM/interface/queue.c b/Robust/src/Runtime/DSTM/interface/queue.c index c892a030..fcb58191 100644 --- a/Robust/src/Runtime/DSTM/interface/queue.c +++ b/Robust/src/Runtime/DSTM/interface/queue.c @@ -58,10 +58,10 @@ void movehead(int size) { void * gettail() { while(tailoffset==headoffset) { //Sleep - pthread_mutex_lock(&qlock); - if (tailoffset==headoffset) - pthread_cond_wait(&qcond, &qlock); - pthread_mutex_unlock(&qlock); + // pthread_mutex_lock(&qlock); + // if (tailoffset==headoffset) + // pthread_cond_wait(&qcond, &qlock); + // pthread_mutex_unlock(&qlock); } if (*((int *)(memory+tailoffset))==-1) { tailoffset=0; //do loop diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index 57610e21..ac986758 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -249,6 +249,7 @@ void *objstrAlloc(unsigned int size) { } } + /* ============================================================= * transRead * -finds the objects either in main heap @@ -345,6 +346,9 @@ int transCommit() { #endif objstrReset(); t_chashreset(); +#ifdef READSET + rd_t_chashreset(); +#endif #ifdef DELAYCOMP dc_t_chashreset(); ptrstack.count=0; @@ -366,6 +370,9 @@ int transCommit() { #endif objstrReset(); t_chashreset(); +#ifdef READSET + rd_t_chashreset(); +#endif #ifdef DELAYCOMP dc_t_chashreset(); ptrstack.count=0; @@ -374,6 +381,7 @@ int transCommit() { #endif return 0; } + /* wait a random amount of time before retrying to commit transaction*/ if(finalResponse == TRANS_SOFT_ABORT) { #ifdef TRANSSTATS @@ -392,6 +400,9 @@ int transCommit() { #endif objstrReset(); t_chashreset(); +#ifdef READSET + rd_t_chashreset(); +#endif #ifdef DELAYCOMP dc_t_chashreset(); ptrstack.count=0; @@ -423,6 +434,38 @@ int transCommit() { free(oidwrlocked); \ } #endif + +#ifdef DELAYCOMP +#define allocarrays 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 +#define allocarrays if (c_numelements<200) { \ + oidrdlocked=rdlocked; \ + oidrdversion=rdversion; \ + oidwrlocked=wrlocked; \ + } else { \ + int size=c_numelements*sizeof(void*); \ + oidrdlocked=malloc(size); \ + oidrdversion=malloc(size); \ + oidwrlocked=malloc(size); \ + } +#endif + + + + /* ================================================== * traverseCache * - goes through the transaction cache and @@ -445,33 +488,8 @@ 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; - oidwrlocked=wrlocked; - } else { - int size=c_numelements*sizeof(void*); - oidrdlocked=malloc(size); - oidrdversion=malloc(size); - oidwrlocked=malloc(size); - } -#endif + allocarrays; + chashlistnode_t *ptr = c_table; /* Represents number of bins in the chash table */ unsigned int size = c_size; @@ -507,12 +525,8 @@ int traverseCache() { return TRANS_SOFT_ABORT; else return TRANS_ABORT; - } } else { -#ifdef DELAYCOMP - //TODO: check to see if we already have lock -#endif if(version == header->version) { /* versions match */ softabort=1; @@ -544,7 +558,7 @@ int traverseCache() { } //end of for #ifdef DELAYCOMP - //acquire other locks + //acquire access set locks unsigned int numoidwrtotal=numoidwrlocked; chashlistnode_t *dc_curr = dc_c_list; @@ -659,9 +673,97 @@ int traverseCache() { return TRANS_SOFT_ABORT; else return TRANS_ABORT; - } } + +#ifdef READSET + //need to validate auxilary readset + rdchashlistnode_t *rd_curr = rd_c_list; + /* Inner loop to traverse the linked list of the cache lookupTable */ + while(likely(rd_curr != NULL)) { + //if the first bin in hash table is empty + unsigned int version=rd_curr->version; + objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t)); + if(header->lock>0) { //object is not locked + if (version!=header->version) { + //have to abort +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + 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; + } + } else { + //maybe we already have lock + if (version==header->version) { + void * key=rd_curr->key; +#ifdef DELAYCOMP + //check to see if it is in the delaycomp table + { + chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4]; + do { + if(node->key == key) + goto nextloopread; + node = node->next; + } while(node != NULL); + } +#endif + //check normal table + { + 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 nextloopread; + } + } + node = node->next; + } while(node != NULL); + } + } +#ifdef DELAYCOMP + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif + +#ifdef STMSTATS + ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + 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; + } + nextloopread: + rd_curr = rd_curr->lnext; + } +#endif /* Decide the final response */ #ifdef DELAYCOMP @@ -697,33 +799,8 @@ 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; - oidwrlocked=wrlocked; - } else { - int size=c_numelements*sizeof(void*); - oidrdlocked=malloc(size); - oidrdversion=malloc(size); - oidwrlocked=malloc(size); - } -#endif + allocarrays; + chashlistnode_t *curr = c_list; /* Inner loop to traverse the linked list of the cache lookupTable */ while(likely(curr != NULL)) { @@ -790,7 +867,7 @@ int alttraverseCache() { //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 + if(write_trylock(&header->lock)) { //can aquire write lock oidwrlocked[numoidwrtotal++] = header; } else { //maybe we already have lock @@ -799,7 +876,7 @@ int alttraverseCache() { do { if(node->key == key) { - objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; + objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; if(STATUS(headeraddr) & DIRTY) { goto nextloop; } @@ -853,7 +930,21 @@ int alttraverseCache() { return TRANS_ABORT; } #ifdef DELAYCOMP - //TODO: check to see if we already have lock + } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) { + //couldn't get lock because we already have it + //check if it is the right version number + if (version!=header->version) { + transAbortProcess(oidwrlocked, numoidwrtotal); +#ifdef STMSTATS + ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; + getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion); +#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); + freearrays; + return TRANS_ABORT; + } #endif } else { /* cannot aquire lock */ if(version == header->version) { @@ -882,6 +973,93 @@ int alttraverseCache() { } } +#ifdef READSET + //need to validate auxilary readset + rdchashlistnode_t *rd_curr = rd_c_list; + /* Inner loop to traverse the linked list of the cache lookupTable */ + while(likely(rd_curr != NULL)) { + //if the first bin in hash table is empty + int version=rd_curr->version; + objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t)); + if(header->lock>0) { //object is not locked + if (version!=header->version) { + //have to abort +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + 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; + } + } else { + if (version==header->version) { + void * key=rd_curr->key; +#ifdef DELAYCOMP + //check to see if it is in the delaycomp table + { + chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4]; + do { + if(node->key == key) + goto nextloopread; + node = node->next; + } while(node != NULL); + } +#endif + //check normal table + { + 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 nextloopread; + } + } + node = node->next; + } while(node != NULL); + } + } +#ifdef DELAYCOMP + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + 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; + } + nextloopread: + rd_curr = rd_curr->lnext; + } +#endif + /* Decide the final response */ #ifdef DELAYCOMP transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); diff --git a/Robust/src/Runtime/STM/stmlock.c b/Robust/src/Runtime/STM/stmlock.c index 15ef3ab9..7da44b66 100644 --- a/Robust/src/Runtime/STM/stmlock.c +++ b/Robust/src/Runtime/STM/stmlock.c @@ -6,6 +6,7 @@ inline void initdsmlocks(volatile unsigned int *addr) { (*addr) = RW_LOCK_BIAS; } +/* int write_trylock(volatile unsigned int *lock) { int retval=0; __asm__ __volatile__("xchgl %0,%1" @@ -14,6 +15,7 @@ int write_trylock(volatile unsigned int *lock) { : "memory"); return retval; } +*/ void write_unlock(volatile unsigned int *lock) { __asm __volatile__("movl $1, %0" : "+m" (*__xg(lock))::"memory"); diff --git a/Robust/src/Runtime/STM/stmlock.h b/Robust/src/Runtime/STM/stmlock.h index 4c79da49..7b9c6d76 100644 --- a/Robust/src/Runtime/STM/stmlock.h +++ b/Robust/src/Runtime/STM/stmlock.h @@ -11,14 +11,14 @@ struct __xchg_dummy { #define __xg(x) ((struct __xchg_dummy *)(x)) void initdsmlocks(volatile unsigned int *addr); -int write_trylock(volatile unsigned int *lock); +//int write_trylock(volatile unsigned int *lock); void write_unlock(volatile unsigned int *lock); /* static inline void initdsmlocks(volatile unsigned int *addr) { (*addr) = RW_LOCK_BIAS; } - +*/ static inline int write_trylock(volatile unsigned int *lock) { int retval=0; __asm__ __volatile__("xchgl %0,%1" @@ -28,6 +28,7 @@ static inline int write_trylock(volatile unsigned int *lock) { return retval; } +/* static inline void write_unlock(volatile unsigned int *lock) { __asm __volatile__("movl $1, %0" : "+m" (*__xg(lock))::"memory"); } diff --git a/Robust/src/Runtime/STM/stmlookup.c b/Robust/src/Runtime/STM/stmlookup.c index 7c7afe33..12345be6 100644 --- a/Robust/src/Runtime/STM/stmlookup.c +++ b/Robust/src/Runtime/STM/stmlookup.c @@ -10,6 +10,197 @@ __thread unsigned int c_threshold; __thread double c_loadfactor; __thread cliststruct_t *c_structs; +#ifdef READSET +__thread rdchashlistnode_t *rd_c_table; +__thread rdchashlistnode_t *rd_c_list; +__thread unsigned int rd_c_size; +__thread unsigned INTPTR rd_c_mask; +__thread unsigned int rd_c_numelements; +__thread unsigned int rd_c_threshold; +__thread double rd_c_loadfactor; +__thread rdcliststruct_t *rd_c_structs; + +void rd_t_chashCreate(unsigned int size, double loadfactor) { + chashtable_t *ctable; + chashlistnode_t *nodes; + int i; + + // Allocate space for the hash table + rd_c_table = calloc(size, sizeof(rdchashlistnode_t)); + rd_c_loadfactor = loadfactor; + rd_c_size = size; + rd_c_threshold=size*loadfactor; + rd_c_mask = (size << 4)-1; + rd_c_structs=calloc(1, sizeof(rdcliststruct_t)); + rd_c_numelements = 0; // Initial number of elements in the hash + rd_c_list=NULL; +} + +void rd_t_chashreset() { + rdchashlistnode_t *ptr = rd_c_table; + int i; + + if (rd_c_numelements<(rd_c_size>>4)) { + rdchashlistnode_t *top=&ptr[rd_c_size]; + rdchashlistnode_t *tmpptr=rd_c_list; + while(tmpptr!=NULL) { + rdchashlistnode_t *next=tmpptr->lnext; + if (tmpptr>=ptr&&tmpptrkey=NULL; + tmpptr->next=NULL; + } + tmpptr=next; + } + } else { + bzero(rd_c_table, sizeof(rdchashlistnode_t)*rd_c_size); + } + while(rd_c_structs->next!=NULL) { + rdcliststruct_t *next=rd_c_structs->next; + free(rd_c_structs); + rd_c_structs=next; + } + rd_c_structs->num = 0; + rd_c_numelements = 0; + rd_c_list=NULL; +} + +//Store objects and their pointers into hash +void rd_t_chashInsertOnce(void * key, unsigned int version) { + rdchashlistnode_t *ptr; + + if (key==NULL) + return; + + if(rd_c_numelements > (rd_c_threshold)) { + //Resize + unsigned int newsize = rd_c_size << 1; + rd_t_chashResize(newsize); + } + + ptr = &rd_c_table[(((unsigned INTPTR)key)&rd_c_mask)>>4]; + + if(ptr->key==0) { + ptr->key=key; + ptr->version=version; + ptr->lnext=rd_c_list; + rd_c_list=ptr; + rd_c_numelements++; + } else { // Insert in the beginning of linked list + rdchashlistnode_t * node; + rdchashlistnode_t *search=ptr; + + //make sure it isn't here + do { + if(search->key == key) { + return; + } + search=search->next; + } while(search != NULL); + + rd_c_numelements++; + if (rd_c_structs->numarray[rd_c_structs->num]; + rd_c_structs->num++; + } else { + //get new list + rdcliststruct_t *tcl=calloc(1,sizeof(rdcliststruct_t)); + tcl->next=rd_c_structs; + rd_c_structs=tcl; + node=&tcl->array[0]; + tcl->num=1; + } + node->key = key; + node->version = version; + node->next = ptr->next; + ptr->next=node; + node->lnext=rd_c_list; + rd_c_list=node; + } +} + +unsigned int rd_t_chashResize(unsigned int newsize) { + rdchashlistnode_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 = rd_c_table; + oldsize = rd_c_size; + rd_c_list=NULL; + + if((node = calloc(newsize, sizeof(rdchashlistnode_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return 1; + } + + rd_c_table = node; //Update the global hashtable upon resize() + rd_c_size = newsize; + rd_c_threshold = newsize * rd_c_loadfactor; + mask=rd_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; + rdchashlistnode_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->version = curr->version; + tmp->lnext=rd_c_list; + rd_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=rd_c_list; + rd_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 rd_t_chashDelete() { + int i; + rdcliststruct_t *ptr=rd_c_structs; + while(ptr!=NULL) { + rdcliststruct_t *next=ptr->next; + free(ptr); + ptr=next; + } + free(rd_c_table); + rd_c_table=NULL; + rd_c_structs=NULL; + rd_c_list=NULL; +} +#endif + #ifdef DELAYCOMP __thread chashlistnode_t *dc_c_table; __thread chashlistnode_t *dc_c_list; @@ -48,7 +239,7 @@ void dc_t_chashreset() { chashlistnode_t *next=tmpptr->lnext; if (tmpptr>=ptr&&tmpptrkey=0; + tmpptr->key=NULL; tmpptr->next=NULL; } tmpptr=next; @@ -247,7 +438,7 @@ void t_chashreset() { chashlistnode_t *next=tmpptr->lnext; if (tmpptr>=ptr&&tmpptrkey=0; + tmpptr->key=NULL; tmpptr->next=NULL; } tmpptr=next; diff --git a/Robust/src/Runtime/STM/stmlookup.h b/Robust/src/Runtime/STM/stmlookup.h index cecb8051..378f1c98 100644 --- a/Robust/src/Runtime/STM/stmlookup.h +++ b/Robust/src/Runtime/STM/stmlookup.h @@ -17,7 +17,6 @@ #define INLINE inline __attribute__((always_inline)) - typedef struct chashlistnode { void * key; void * val; //this can be cast to another type or used to point to a larger structure @@ -49,7 +48,6 @@ unsigned int t_chashResize(unsigned int newsize); void t_chashDelete(); void t_chashreset(); - extern __thread chashlistnode_t *c_table; extern __thread chashlistnode_t *c_list; extern __thread unsigned int c_size; @@ -59,6 +57,38 @@ extern __thread unsigned int c_threshold; extern __thread double c_loadfactor; extern __thread cliststruct_t *c_structs; +#ifdef READSET + +typedef struct rdchashlistnode { + void * key; + unsigned int version; + struct rdchashlistnode *next; + struct rdchashlistnode *lnext; +} rdchashlistnode_t; + +typedef struct rdclist { + struct rdchashlistnode array[NUMCLIST]; + int num; + struct rdclist *next; +} rdcliststruct_t; + + +extern __thread rdchashlistnode_t *rd_c_table; +extern __thread rdchashlistnode_t *rd_c_list; +extern __thread unsigned int rd_c_size; +extern __thread unsigned INTPTR rd_c_mask; +extern __thread unsigned int rd_c_numelements; +extern __thread unsigned int rd_c_threshold; +extern __thread double rd_c_loadfactor; +extern __thread rdcliststruct_t *rd_c_structs; + +void rd_t_chashCreate(unsigned int size, double loadfactor); +void rd_t_chashInsertOnce(void * key, unsigned int val); +unsigned int rd_t_chashResize(unsigned int newsize); +void rd_t_chashDelete(); +void rd_t_chashreset(); +#endif + #ifdef DELAYCOMP extern __thread chashlistnode_t *dc_c_table; extern __thread chashlistnode_t *dc_c_list; @@ -76,5 +106,4 @@ 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 05937ffa..318f6cfb 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -8,7 +8,7 @@ #define TRANS_SOFT_ABORT 12 #define TRANS_ABORT 13 #define TRANS_COMMIT 14 - +#define TRANS_ABORT_RETRY 15 /* ======================== * Library header files @@ -107,6 +107,19 @@ typedef struct objheader { } while(1); \ }} +#define TRANSREADRD(x,y) { \ + void * inputvalue; \ + if ((inputvalue=y)==NULL) x=NULL;\ + else { \ + chashlistnode_t * cnodetmp=&c_table[(((unsigned INTPTR)inputvalue)&c_mask)>>4]; \ + do { \ + if (cnodetmp->key==inputvalue) {x=cnodetmp->val; break;} \ + cnodetmp=cnodetmp->next; \ + if (cnodetmp==NULL) {if (((struct ___Object___*)inputvalue)->___objstatus___&NEW) {x=inputvalue; break;} else \ + {x=inputvalue;rd_t_chashInsertOnce(inputvalue, ((objheader_t *)inputvalue)[-1].version); break;}} \ + } while(1); \ + }} + /* ================================= * Data structures * ================================= @@ -169,6 +182,9 @@ objheader_t *transCreateObj(void * ptr, unsigned int size); unsigned int getNewOID(void); void *objstrAlloc(unsigned int size); __attribute__((pure)) void *transRead(void *, void *); +#ifdef READSET +__attribute__((pure)) void *transReadOnly(void *); +#endif #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); diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c index 1ef15582..5736285f 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -26,10 +26,10 @@ #define NUMPTRS 100 -#define INITIALHEAPSIZE 256*1024*1024 -#define GCPOINT(x) ((int)((x)*0.99)) +#define INITIALHEAPSIZE 1024*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) ((int)(x+y))*2 +#define HEAPSIZE(x,y) ((INTPTR)(x+y))*2 #ifdef TASK extern struct genhashtable * activetasks; @@ -742,9 +742,9 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) { /* Grow the to heap if necessary */ { - int curr_heapsize=curr_heaptop-curr_heapbase; - int to_heapsize=to_heaptop-to_heapbase; - int last_heapsize=0; + INTPTR curr_heapsize=curr_heaptop-curr_heapbase; + INTPTR to_heapsize=to_heaptop-to_heapbase; + INTPTR last_heapsize=0; if (lastgcsize>0) { last_heapsize=HEAPSIZE(lastgcsize, size); if ((last_heapsize&7)!=0) diff --git a/Robust/src/Runtime/thread.c b/Robust/src/Runtime/thread.c index 0180ef57..66b9d354 100644 --- a/Robust/src/Runtime/thread.c +++ b/Robust/src/Runtime/thread.c @@ -180,6 +180,9 @@ void initializethreads() { t_cache = objstrCreate(1048576); t_reserve=NULL; t_chashCreate(CHASH_SIZE, CLOADFACTOR); +#ifdef READSET + rd_t_chashCreate(CHASH_SIZE, CLOADFACTOR); +#endif #ifdef DELAYCOMP dc_t_chashCreate(CHASH_SIZE, CLOADFACTOR); ptrstack.count=0; @@ -247,6 +250,9 @@ void initthread(struct ___Thread___ * ___this___) { t_cache = objstrCreate(1048576); t_reserve=NULL; t_chashCreate(CHASH_SIZE, CLOADFACTOR); +#ifdef READSET + rd_t_chashCreate(CHASH_SIZE, CLOADFACTOR); +#endif #ifdef DELAYCOMP dc_t_chashCreate(CHASH_SIZE, CLOADFACTOR); ptrstack.count=0; -- 2.34.1