X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FRuntime%2FSTM%2Fstm.c;h=45e4dd4cf577433b49efed386c65b6d3f1861054;hb=c368a66eea791b5bd74165afe66e92d68092ce09;hp=2cef92ee5a217c23e7de18675a2ef213afc6a0ef;hpb=2d10b09e1a6e3c25fedec1ef74343c5f48c85f6f;p=IRC.git diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index 2cef92ee..45e4dd4c 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -18,6 +18,20 @@ __thread objstr_t *t_cache; __thread objstr_t *t_reserve; __thread struct objlist * newobjs; +#ifdef SANDBOX +#include "sandbox.h" +#endif + +#ifdef DELAYCOMP +#include "delaycomp.h" +__thread struct pointerlist ptrstack; +__thread struct primitivelist primstack; +__thread struct branchlist branchstack; +struct pointerlist *c_ptrstack; +struct primitivelist *c_primstack; +struct branchlist *c_branchstack; +#endif + #ifdef TRANSSTATS int numTransCommit = 0; int numTransAbort = 0; @@ -26,59 +40,25 @@ int nSoftAbortCommit = 0; int nSoftAbortAbort = 0; #endif -#ifdef STMSTATS -/* Thread variable for locking/unlocking */ -__thread threadrec_t *trec; -__thread struct objlist * lockedobjs; -/** Global lock **/ -int typesCausingAbort[TOTALNUMCLASSANDARRAY]; -/******Keep track of objects and types causing aborts******/ -/* TODO uncomment for later use -#define DEBUGSTMSTAT(args...) { \ - printf(args); \ - fflush(stdout); \ -} -*/ -#define DEBUGSTMSTAT(args...) -#else -#define DEBUGSTMSTAT(args...) -#endif - -#ifdef STMDEBUG -#define DEBUGSTM(x...) printf(x); -#else -#define DEBUGSTM(x...) -#endif +void * A_memcpy (void * dest, const void * src, size_t count) { + int off=0; + INTPTR *desti=(INTPTR *)dest; + INTPTR *srci=(INTPTR *)src; -#ifdef STMSTATS -/*** Global variables *****/ -objlockstate_t *objlockscope; -/** - * ABORTCOUNT - * params: object header - * Increments the abort count for each object - **/ -void ABORTCOUNT(objheader_t * x) { - x->abortCount++; - if (x->abortCount > MAXABORTS && (x->riskyflag != 1)) { - //makes riskflag sticky - pthread_mutex_lock(&lockedobjstore); - if (objlockscope->offsetobjlock=&(objlockscope->lock[objlockscope->offset++]); - } else { - objlockstate_t *tmp=malloc(sizeof(objlockstate_t)); - tmp->next=objlockscope; - tmp->offset=1; - x->objlock=&(tmp->lock[0]); - objlockscope=tmp; - } - pthread_mutex_unlock(&lockedobjstore); - pthread_mutex_init(x->objlock, NULL); - //should put a memory barrier here - x->riskyflag = 1; + //word copy + while(count>=sizeof(INTPTR)) { + desti[off]=srci[off]; + off+=1; + count-=sizeof(INTPTR); + } + off*=sizeof(INTPTR); + //byte copy + while(count>0) { + ((char *)dest)[off]=((char *)src)[off]; + off++; + count--; } } -#endif /* ================================================== * stmStartup @@ -89,44 +69,6 @@ int stmStartup() { return 0; } -/* ====================================== - * objstrCreate - * - create an object store of given size - * ====================================== - */ -objstr_t *objstrCreate(unsigned int size) { - objstr_t *tmp; - if((tmp = calloc(1, (sizeof(objstr_t) + size))) == NULL) { - printf("%s() Calloc error at line %d, %s\n", __func__, __LINE__, __FILE__); - return NULL; - } - tmp->size = size; - tmp->next = NULL; - tmp->top = tmp + 1; //points to end of objstr_t structure! - return tmp; -} - -void objstrReset() { - while(t_cache->next!=NULL) { - objstr_t *next=t_cache->next; - t_cache->next=t_reserve; - t_reserve=t_cache; - t_cache=next; - } - t_cache->top=t_cache+1; -} - -//free entire list, starting at store -void objstrDelete(objstr_t *store) { - objstr_t *tmp; - while (store != NULL) { - tmp = store->next; - free(store); - store = tmp; - } - return; -} - /* ================================================= * transStart * This function initializes things required in the @@ -135,6 +77,11 @@ void objstrDelete(objstr_t *store) { */ void transStart() { //Transaction start is currently free...commit and aborting is not +#ifdef DELAYCOMP + c_ptrstack=&ptrstack; + c_primstack=&primstack; + c_branchstack=&branchstack; +#endif } /* ======================================================= @@ -142,10 +89,16 @@ void transStart() { * This function creates objects in the transaction record * ======================================================= */ +#ifdef STMARRAY +objheader_t *transCreateObj(void * ptr, unsigned int size, int bytelength) { + char *tmpchar = mygcmalloc(ptr, (sizeof(objheader_t) + size)); + objheader_t *tmp = (objheader_t *) (tmpchar+bytelength); +#else objheader_t *transCreateObj(void * ptr, unsigned int size) { objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size)); - objheader_t *retval=&tmp[1]; - tmp->lock=RW_LOCK_BIAS; +#endif + objheader_t *retval=tmp+1; + tmp->lock=SWAP_LOCK_BIAS; tmp->version = 1; //initialize obj lock to the header STATUS(tmp)=NEW; @@ -176,89 +129,94 @@ void randomdelay(int softaborted) { return; } -/* ============================================== - * objstrAlloc - * - allocate space in an object store - * ============================================== - */ -void *objstrAlloc(unsigned int size) { - void *tmp; - int i=0; - objstr_t *store=t_cache; - if ((size&7)!=0) { - size+=(8-(size&7)); - } - - for(; i<2; i++) { - if (OSFREE(store)>=size) { - tmp=store->top; - store->top +=size; - return tmp; - } - if ((store=store->next)==NULL) - break; - } - - { - unsigned int newsize=size>DEFAULT_OBJ_STORE_SIZE ? size : DEFAULT_OBJ_STORE_SIZE; - objstr_t **otmp=&t_reserve; - objstr_t *ptr; - while((ptr=*otmp)!=NULL) { - if (ptr->size>=newsize) { - //remove from list - *otmp=ptr->next; - ptr->next=t_cache; - t_cache=ptr; - ptr->top=((char *)(&ptr[1]))+size; - return &ptr[1]; - } - } - - objstr_t *os=(objstr_t *)calloc(1,(sizeof(objstr_t) + newsize)); - void *nptr=&os[1]; - os->next=t_cache; - t_cache=os; - os->size=newsize; - os->top=((char *)nptr)+size; - return nptr; - } -} - /* ============================================================= * transRead * -finds the objects either in main heap * -copies the object into the transaction cache * ============================================================= */ -__attribute__((pure)) void *transRead(void * oid, void *gl) { + +//void *TR(void *x, void * y, void *z) { +// 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=transRead(inputvalue,z); asm volatile ("" : "=m" (c_table),"\=m" (c_mask)); break;}} +// } while(1); +// } +// return x; +//} + +//__attribute__ ((pure)) +void *transRead(void * oid, void *gl) { objheader_t *tmp, *objheader; objheader_t *objcopy; int size; - /* Read from the main heap */ - //No lock for now objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t)); - GETSIZE(size, header); - size += sizeof(objheader_t); - objcopy = (objheader_t *) objstrAlloc(size); #ifdef STMSTATS header->accessCount++; - //FIXME riskratio fix - //float riskratio = ((header->abortCount)/(header->accessCount)); - //DEBUGSTMSTAT("type: %d, header->abortCount: %d, header->accessCount: %d, riskratio: %f\n", TYPE(header), header->abortCount, header->accessCount, riskratio); - //DEBUGSTMSTAT("type: %d, header->abortCount: %d, header->accessCount: %d\n", TYPE(header), header->abortCount, header->accessCount); - //if(header->abortCount > MAXABORTS && riskratio > NEED_LOCK_THRESHOLD) { if(header->riskyflag) { - needLock(header,gl); + header=needLock(header,gl); + } +#endif +#ifdef STMARRAY + int type=TYPE(header); + if (type>=NUMCLASSES) { + int basesize=((struct ArrayObject *)oid)->___length___*classsize[type]; + basesize=(basesize+LOWMASK)&HIGHMASK; + int metasize=sizeof(int)*2*(basesize>>INDEXSHIFT); + size = basesize + sizeof(objheader_t)+metasize+sizeof(struct ArrayObject); + char *tmpptr = (char *) objstrAlloc(size); + bzero(tmpptr, metasize);//clear out stm data + objcopy=(objheader_t *) (tmpptr+metasize); + A_memcpy(objcopy, header, sizeof(objheader_t)+sizeof(struct ArrayObject)); //copy the metadata and base array info + } else { + GETSIZE(size, header); + size += sizeof(objheader_t); + objcopy = (objheader_t *) objstrAlloc(size); + A_memcpy(objcopy, header, size); } +#else + GETSIZE(size, header); + size += sizeof(objheader_t); + objcopy = (objheader_t *) objstrAlloc(size); + A_memcpy(objcopy, header, size); +#endif +#ifdef STMSTATS + /* keep track of the object's access sequence in a transaction */ + objheader_t *tmpheader = objcopy; + tmpheader->accessCount = ++t_objnumcount; #endif - memcpy(objcopy, header, size); /* Insert into cache's lookup table */ STATUS(objcopy)=0; + if (((unsigned INTPTR)oid)<((unsigned INTPTR ) curr_heapbase)|| ((unsigned INTPTR)oid) >((unsigned INTPTR) curr_heapptr)) + printf("ERROR! Bad object address!\n"); t_chashInsert(oid, &objcopy[1]); return &objcopy[1]; } +#ifdef STMARRAY +//caller needs to mark data as present + void arraycopy(struct ArrayObject *oid, int byteindex) { + struct ArrayObject * orig=(struct ArrayObject *) oid->___objlocation___; + int baseoffset=byteindex&HIGHMASK; + unsigned int mainversion; + int baseindex=baseoffset>>INDEXSHIFT; + GETVERSIONVAL(mainversion, orig, baseindex); + SETVERSION(oid, baseindex, mainversion); + A_memcpy(((char *)&oid[1])+baseoffset, ((char *)&orig[1])+baseoffset, INDEXLENGTH); + if (oid->lowindex>baseoffset) + oid->lowindex=baseoffset; + if (oid->highindexhighindex=baseoffset; + } +#endif + void freenewobjs() { struct objlist *ptr=newobjs; while(ptr->next!=NULL) { @@ -270,592 +228,3 @@ void freenewobjs() { newobjs=ptr; } -#ifdef STMSTATS -void freelockedobjs() { - struct objlist *ptr=lockedobjs; - while(ptr->next!=NULL) { - struct objlist *tmp=ptr->next; - free(ptr); - ptr=tmp; - } - ptr->offset=0; - lockedobjs=ptr; -} -#endif - -/* ================================================================ - * transCommit - * - This function initiates the transaction commit process - * - goes through the transaction cache and decides - * - a final response - * ================================================================ - */ -int transCommit() { - int softaborted=0; - do { - /* Look through all the objects in the transaction hash table */ - int finalResponse; - if (c_numelements<(c_size>>3)) - finalResponse= alttraverseCache(); - else - finalResponse= traverseCache(); - if(finalResponse == TRANS_ABORT) { -#ifdef TRANSSTATS - numTransAbort++; - if (softaborted) { - nSoftAbortAbort++; - } -#endif - freenewobjs(); -#ifdef STMSTATS - freelockedobjs(); -#endif - objstrReset(); - t_chashreset(); - return TRANS_ABORT; - } - if(finalResponse == TRANS_COMMIT) { -#ifdef TRANSSTATS - numTransCommit++; - if (softaborted) { - nSoftAbortCommit++; - } -#endif - freenewobjs(); -#ifdef STMSTATS - freelockedobjs(); -#endif - objstrReset(); - t_chashreset(); - return 0; - } - /* wait a random amount of time before retrying to commit transaction*/ - if(finalResponse == TRANS_SOFT_ABORT) { -#ifdef TRANSSTATS - nSoftAbort++; -#endif - softaborted++; - if (softaborted>4) { - //retry if too many soft aborts - freenewobjs(); -#ifdef STMSTATS - freelockedobjs(); -#endif - objstrReset(); - t_chashreset(); - return TRANS_ABORT; - } - randomdelay(softaborted); - } else { - printf("Error: in %s() Unknown outcome", __func__); - exit(-1); - } - } while (1); -} - -/* ================================================== - * traverseCache - * - goes through the transaction cache and - * - decides if a transaction should commit or abort - * ================================================== - */ -int traverseCache() { - /* Create info to keep track of objects that can be locked */ - int numoidrdlocked=0; - int numoidwrlocked=0; - void * rdlocked[200]; - int rdversion[200]; - void * wrlocked[200]; - int softabort=0; - int i; - void ** oidrdlocked; - void ** oidwrlocked; - int * oidrdversion; - 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); - } - chashlistnode_t *ptr = c_table; - /* Represents number of bins in the chash table */ - unsigned int size = c_size; - for(i = 0; ikey == NULL) - break; - objheader_t * headeraddr=&((objheader_t *) curr->val)[-1]; - objheader_t *header=(objheader_t *)(((char *)curr->key)-sizeof(objheader_t)); - unsigned int version = headeraddr->version; - - if(STATUS(headeraddr) & DIRTY) { - /* Read from the main heap and compare versions */ - if(write_trylock(&header->lock)) { //can aquire write lock - if (version == header->version) { /* versions match */ - /* Keep track of objects locked */ - oidwrlocked[numoidwrlocked++] = OID(header); - } else { - oidwrlocked[numoidwrlocked++] = OID(header); - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(i+1, size, (void *)(curr->next), NULL, 1); -#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); - } - return TRANS_ABORT; - } - } else { /* cannot aquire lock */ - if(version == header->version) { - /* versions match */ - softabort=1; - } else { - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(i+1, size, (void *)(curr->next), NULL, 1); -#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); - } - return TRANS_ABORT; - } - } - } else { - oidrdversion[numoidrdlocked]=version; - oidrdlocked[numoidrdlocked++] = header; - } - curr = curr->next; - } - } //end of for - - //THIS IS THE SERIALIZATION POINT ***** - - for(i=0; ilock>0) { //not write locked - if(version != header->version) { /* versions do not match */ - oidrdlocked[numoidrdlocked++] = OID(header); - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(i+1, numoidrdlocked, oidrdlocked, (void *) oidrdversion, 0); -#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); - } - return TRANS_ABORT; - } - } else { /* cannot aquire lock */ - //do increment as we didn't get lock - if(version == header->version) { - softabort=1; - } else { - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(i+1, numoidrdlocked, oidrdlocked, (void *) oidrdversion, 0); -#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); - } - return TRANS_ABORT; - } - } - } - - /* Decide the final response */ - if (softabort) { - transAbortProcess(oidwrlocked, numoidwrlocked); - DEBUGSTM("Soft Abort: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } - return TRANS_SOFT_ABORT; - } else { - transCommitProcess(oidwrlocked, numoidwrlocked); - DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } - return TRANS_COMMIT; - } -} - -/* ================================================== - * alttraverseCache - * - goes through the transaction cache and - * - decides if a transaction should commit or abort - * ================================================== - */ -int alttraverseCache() { - /* Create info to keep track of objects that can be locked */ - int numoidrdlocked=0; - int numoidwrlocked=0; - void * rdlocked[200]; - int rdversion[200]; - void * wrlocked[200]; - int softabort=0; - int i; - void ** oidrdlocked; - int * oidrdversion; - void ** oidwrlocked; - 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); - } - chashlistnode_t *curr = c_list; - /* Inner loop to traverse the linked list of the cache lookupTable */ - while(curr != NULL) { - //if the first bin in hash table is empty - objheader_t * headeraddr=&((objheader_t *) curr->val)[-1]; - objheader_t *header=(objheader_t *)(((char *)curr->key)-sizeof(objheader_t)); - unsigned int version = headeraddr->version; - - if(STATUS(headeraddr) & DIRTY) { - /* Read from the main heap and compare versions */ - if(write_trylock(&header->lock)) { //can aquire write lock - if (version == header->version) { /* versions match */ - /* Keep track of objects locked */ - oidwrlocked[numoidwrlocked++] = OID(header); - } else { - oidwrlocked[numoidwrlocked++] = OID(header); - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(0, 1, (void *) curr->next, NULL, 1); -#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); - } - return TRANS_ABORT; - } - } else { /* cannot aquire lock */ - if(version == header->version) { - /* versions match */ - softabort=1; - } else { - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(0, 1, (void *) curr->next, NULL, 1); -#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); - } - return TRANS_ABORT; - } - } - } else { - /* Read from the main heap and compare versions */ - oidrdversion[numoidrdlocked]=version; - oidrdlocked[numoidrdlocked++] = header; - } - curr = curr->lnext; - } - //THIS IS THE SERIALIZATION POINT ***** - for(i=0; ilock>=0) { - if(version != header->version) { - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(i+1, numoidrdlocked, oidrdlocked, (void *)oidrdversion, 0); -#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); - } - return TRANS_ABORT; - } - } else { /* cannot aquire lock */ - if(version == header->version) { - softabort=1; - } else { - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - getTotalAbortCount(i+1, numoidrdlocked, oidrdlocked, (void *)oidrdversion, 0); -#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); - } - return TRANS_ABORT; - } - } - } - - /* Decide the final response */ - if (softabort) { - transAbortProcess(oidwrlocked, numoidwrlocked); - DEBUGSTM("Soft Abort: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } - return TRANS_SOFT_ABORT; - } else { - transCommitProcess(oidwrlocked, numoidwrlocked); - DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - if (c_numelements>=200) { - free(oidrdlocked); - free(oidrdversion); - free(oidwrlocked); - } - return TRANS_COMMIT; - } -} - - -/* ================================== - * transAbortProcess - * - * ================================= - */ -int transAbortProcess(void **oidwrlocked, int numoidwrlocked) { - int i; - objheader_t *header; - /* Release read locks */ - - /* Release write locks */ - for(i=0; i< numoidwrlocked; i++) { - /* Read from the main heap */ - header = (objheader_t *)(((char *)(oidwrlocked[i])) - sizeof(objheader_t)); - write_unlock(&header->lock); - } - -#ifdef STMSTATS - /* clear trec and then release objects locked */ - struct objlist *ptr=lockedobjs; - while(ptr!=NULL) { - int max=ptr->offset; - for(i=0; iobjs[i]) - sizeof(objheader_t)); - header->trec = NULL; - pthread_mutex_unlock(header->objlock); - } - ptr=ptr->next; - } -#endif -} - -/* ================================== - * transCommitProcess - * - * ================================= - */ -int transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { - objheader_t *header; - void *ptrcreate; - int i; - struct objlist *ptr=newobjs; - while(ptr!=NULL) { - int max=ptr->offset; - for(i=0; iobjs[i])->___objstatus___=0; - } - ptr=ptr->next; - } - - /* Copy from transaction cache -> main object store */ - for (i = 0; i < numoidwrlocked; i++) { - /* Read from the main heap */ - header = (objheader_t *)(((char *)(oidwrlocked[i])) - sizeof(objheader_t)); - int tmpsize; - GETSIZE(tmpsize, header); - struct ___Object___ *dst=(struct ___Object___*)oidwrlocked[i]; - struct ___Object___ *src=t_chashSearch(oidwrlocked[i]); - dst->___cachedCode___=src->___cachedCode___; - dst->___cachedHash___=src->___cachedHash___; - memcpy(&dst[1], &src[1], tmpsize-sizeof(struct ___Object___)); - __asm__ __volatile__("": : :"memory"); - header->version++; - } - __asm__ __volatile__("": : :"memory"); - - /* Release write locks */ - for(i=0; i< numoidwrlocked; i++) { - header = (objheader_t *)(((char *)(oidwrlocked[i])) - sizeof(objheader_t)); - write_unlock(&header->lock); - } - -#ifdef STMSTATS - /* clear trec and then release objects locked */ - ptr=lockedobjs; - while(ptr!=NULL) { - int max=ptr->offset; - for(i=0; iobjs[i])) - sizeof(objheader_t)); - header->trec = NULL; - pthread_mutex_unlock(header->objlock); - } - ptr=ptr->next; - } -#endif - - return 0; -} - -/** ======================================================================================== - * getTotalAbortCount - * params : start: start index of the loop - * : stop: stop index of the loop - * : startptr: pointer that points to where to start looking in the array/ linked list - * 0='r'/1='w' if found when visiting objects read/ objects modified - * ========================================================================================= - **/ -#ifdef STMSTATS -void getTotalAbortCount(int start, int stop, void *startptr, void *checkptr, int type) { - int i; - if(type) { - int isFirstTime = 0; - chashlistnode_t *curr = (chashlistnode_t *) startptr; - chashlistnode_t *ptr = c_table; - for(i = start; i < stop; i++) { - if(!isFirstTime) - curr = &ptr[i]; - /* Inner loop to traverse the linked list of the cache lookupTable */ - while(curr != NULL) { - if(curr->key == NULL) - break; - objheader_t * headeraddr=&((objheader_t *) curr->val)[-1]; - objheader_t *header=(objheader_t *)(((char *)curr->key)-sizeof(objheader_t)); - unsigned int version = headeraddr->version; - /* versions do not match */ - if(version != header->version) { - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - } - curr = curr->next; - } - isFirstTime = 1; - } - } else { - /* Go through oids read that are locked */ - for(i = start; i < stop; i++) { - objheader_t *header = ((void **)startptr)[i]; - unsigned int version = ((int *)checkptr)[i]; - if(version != header->version) { /* versions do not match */ - ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; - } - } - } -} - -/** - * needLock - * params: Object header - * Locks an object that causes aborts - **/ -void needLock(objheader_t *header, void *gl) { - int lockstatus; - threadrec_t *ptr; - while((lockstatus = pthread_mutex_trylock(header->objlock)) - && ((ptr = header->trec) == NULL)) { //retry - ; - } - if(lockstatus==0) { //acquired lock - /* Set trec */ - header->trec = trec; - } else { //failed to get lock - trec->blocked=1; - //memory barrier - __asm__ __volatile__("":::"memory"); - //see if other thread is blocked - if(ptr->blocked == 1) { - //it might be block, so ignore lock and clear our blocked flag - trec->blocked=0; - return; - } else { -#ifdef PRECISE_GC - struct listitem *tmp=stopforgc((struct garbagelist *)gl); -#endif - //grab lock and wait our turn - pthread_mutex_lock(header->objlock); -#ifdef PRECISE_GC - restartaftergc(tmp); -#endif - /* we have lock, so we are not blocked anymore */ - trec->blocked = 0; - /* Set our trec */ - header->trec = trec; - } - } - //trec->blocked is zero now - - /* Save the locked object */ - if (lockedobjs->offsetobjs[lockedobjs->offset++]=OID(header); - } else { - struct objlist *tmp=malloc(sizeof(struct objlist)); - tmp->next=lockedobjs; - tmp->objs[0]=OID(header); - tmp->offset=1; - lockedobjs=tmp; - } -} -#endif