X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FRuntime%2FSTM%2Fstm.c;h=45e4dd4cf577433b49efed386c65b6d3f1861054;hb=c368a66eea791b5bd74165afe66e92d68092ce09;hp=dc0dcfb6cac16a72ff6634c56ef0d59655ecb1bb;hpb=bcea7094f53611afb1bbf2cafd9cb362353f47cc;p=IRC.git diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index dc0dcfb6..45e4dd4c 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -1,10 +1,10 @@ /* ============================================================ - * singleTMCommit.c + * singleTMCommit.c * - single thread commit on local machine * ============================================================= * Copyright (c) 2009, University of California, Irvine, USA. * All rights reserved. - * Author: Alokika Dash + * Author: Alokika Dash * adash@uci.edu * ============================================================= * @@ -12,75 +12,95 @@ #include "tm.h" #include "garbage.h" -/* Thread transaction variables */ + +/* Per thread transaction variables */ __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; int nSoftAbort = 0; +int nSoftAbortCommit = 0; +int nSoftAbortAbort = 0; #endif +void * A_memcpy (void * dest, const void * src, size_t count) { + int off=0; + INTPTR *desti=(INTPTR *)dest; + INTPTR *srci=(INTPTR *)src; + + //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--; + } +} /* ================================================== * stmStartup - * This function starts up the transaction runtime. + * This function starts up the transaction runtime. * ================================================== */ 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; -} - -//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 + * This function initializes things required in the * transaction start * ================================================= */ void transStart() { - t_cache = objstrCreate(1048576); - t_chashCreate(CHASH_SIZE, CLOADFACTOR); + //Transaction start is currently free...commit and aborting is not +#ifdef DELAYCOMP + c_ptrstack=&ptrstack; + c_primstack=&primstack; + c_branchstack=&branchstack; +#endif } /* ======================================================= * transCreateObj - * This function creates objects in the transaction record + * 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; // don't insert into table if (newobjs->offset=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 *os=(objstr_t *)calloc(1,(sizeof(objstr_t) + newsize)); - void *ptr=&os[1]; - os->next=store; - (*osptr)=os; - os->size=newsize; - os->top=((char *)ptr)+size; - return ptr; - } -} - /* ============================================================= * transRead * -finds the objects either in main heap * -copies the object into the transaction cache * ============================================================= */ -__attribute__((pure)) void *transRead(void * oid) { - unsigned int machinenumber; + +//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; - //quick case for new objects - if (((struct ___Object___ *)oid)->___objstatus___ & NEW) - return oid; - - /* Read from the main heap */ - //No lock for now - objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t)); + objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t)); +#ifdef STMSTATS + header->accessCount++; + if(header->riskyflag) { + 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(&t_cache, size); - memcpy(objcopy, header, size); + 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 /* Insert into cache's lookup table */ STATUS(objcopy)=0; - t_chashInsert((unsigned int)oid, &objcopy[1]); + 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) { @@ -183,208 +228,3 @@ void freenewobjs() { newobjs=ptr; } -/* ================================================================ - * transCommit - * - This function initiates the transaction commit process - * - goes through the transaction cache and decides - * - a final response - * ================================================================ - */ -int transCommit() { - do { - /* Look through all the objects in the transaction hash table */ - int finalResponse = traverseCache(); - if(finalResponse == TRANS_ABORT) { -#ifdef TRANSSTATS - numTransAbort++; -#endif - freenewobjs(); - objstrDelete(t_cache); - t_chashDelete(); - return TRANS_ABORT; - } - if(finalResponse == TRANS_COMMIT) { -#ifdef TRANSSTATS - numTransCommit++; -#endif - freenewobjs(); - objstrDelete(t_cache); - t_chashDelete(); - return 0; - } - /* wait a random amount of time before retrying to commit transaction*/ - if(finalResponse == TRANS_SOFT_ABORT) { -#ifdef TRANSSTATS - nSoftAbort++; -#endif - randomdelay(); - } 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; - unsigned int oidrdlocked[c_numelements]; - unsigned int oidwrlocked[c_numelements]; - int softabort=0; - int i; - chashlistnode_t *ptr = c_table; - /* Represents number of bins in the chash table */ - unsigned int size = c_size; - for(i = 0; ikey == 0) - break; - objheader_t * headeraddr=&((objheader_t *) curr->val)[-1]; - - unsigned int version = headeraddr->version; - objheader_t *header=(objheader_t *) (((char *)curr->key)-sizeof(objheader_t)); - - 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(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked); - return TRANS_ABORT; - } - } else { /* cannot aquire lock */ - if(version == header->version) /* versions match */ - softabort=1; - else { - transAbortProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked); - return TRANS_ABORT; - } - } - } else { - /* Read from the main heap and compare versions */ - if(read_trylock(&header->lock)) { //can further aquire read locks - if(version == header->version) {/* versions match */ - oidrdlocked[numoidrdlocked++] = OID(header); - } else { - oidrdlocked[numoidrdlocked++] = OID(header); - transAbortProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked); - return TRANS_ABORT; - } - } else { /* cannot aquire lock */ - if(version == header->version) - softabort=1; - else { - transAbortProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked); - return TRANS_ABORT; - } - } - } - - curr = curr->next; - } - } //end of for - - /* Decide the final response */ - if (softabort) { - transAbortProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked); - return TRANS_SOFT_ABORT; - } else { - transCommitProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked); - return TRANS_COMMIT; - } -} - -/* =========================================================================== - * decideResponse - * - increments counters that keep track of objects read, modified or locked - * - updates the oids locked and oids newly created - * =========================================================================== - */ - - -/* ================================== - * transAbortProcess - * - * ================================= - */ -int transAbortProcess(unsigned int *oidrdlocked, int *numoidrdlocked, unsigned int *oidwrlocked, int *numoidwrlocked) { - int i; - objheader_t *header; - /* Release read locks */ - for(i=0; i< *numoidrdlocked; i++) { - /* Read from the main heap */ - header = (objheader_t *)(((char *)(oidrdlocked[i])) - sizeof(objheader_t)); - read_unlock(&header->lock); - } - - /* 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); - } -} - -/* ================================== - * transCommitProcess - * - * ================================= - */ -int transCommitProcess(unsigned int *oidrdlocked, int *numoidrdlocked, - unsigned int *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___)); - header->version += 1; - } - - /* Release read locks */ - for(i=0; i< *numoidrdlocked; i++) { - /* Read from the main heap */ - header = (objheader_t *)(((char *)(oidrdlocked[i])) - sizeof(objheader_t)); - read_unlock(&header->lock); - } - - /* Release write locks */ - for(i=0; i< *numoidwrlocked; i++) { - header = (objheader_t *)(((char *)(oidwrlocked[i])) - sizeof(objheader_t)); - write_unlock(&header->lock); - } - - return 0; -} -