From: adash Date: Wed, 6 May 2009 21:06:38 +0000 (+0000) Subject: locking technique for risky objects enabled X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e60d4e95549c034dfca25992e4041785078b541f;p=IRC.git locking technique for risky objects enabled --- diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index ed87d172..71bb1214 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -26,12 +26,18 @@ int nSoftAbortAbort = 0; #endif #ifdef STMSTATS +/* Thread variable for locking/unlocking */ +__thread threadrec_t trec; +__thread struct objlist * lockedobjs; int typesCausingAbort[TOTALNUMCLASSANDARRAY]; /******Keep track of objects and types causing aborts******/ +/*TODO #define DEBUGSTMSTAT(args...) { \ - printf(args); \ - fflush(stdout); \ + printf(args); \ + fflush(stdout); \ } +*/ +#define DEBUGSTMSTAT(args...) #else #define DEBUGSTMSTAT(args...) #endif @@ -110,6 +116,12 @@ objheader_t *transCreateObj(void * ptr, unsigned int size) { objheader_t *retval=&tmp[1]; tmp->lock=RW_LOCK_BIAS; tmp->version = 1; + tmp->abortCount = 0; + tmp->accessCount = 0; + tmp->riskyflag = 0; + tmp->trec = NULL; + //initialize obj lock + pthread_mutex_init(&tmp->objlock, NULL); STATUS(tmp)=NEW; // don't insert into table if (newobjs->offsetaccessCount++; + //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->abortCount > MAXABORTS) { + /* Set risky flag */ + header->riskyflag = 1; + /* Need locking */ + needLock(header); + } #endif /* Insert into cache's lookup table */ STATUS(objcopy)=0; @@ -224,6 +247,19 @@ 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 @@ -248,6 +284,9 @@ int transCommit() { } #endif freenewobjs(); +#ifdef STMSTATS + freelockedobjs(); +#endif objstrReset(); t_chashreset(); return TRANS_ABORT; @@ -260,6 +299,9 @@ int transCommit() { } #endif freenewobjs(); +#ifdef STMSTATS + freelockedobjs(); +#endif objstrReset(); t_chashreset(); return 0; @@ -273,6 +315,9 @@ int transCommit() { if (softaborted>4) { //retry if too many soft aborts freenewobjs(); +#ifdef STMSTATS + freelockedobjs(); +#endif objstrReset(); t_chashreset(); return TRANS_ABORT; @@ -617,6 +662,20 @@ int transAbortProcess(void **oidwrlocked, int numoidwrlocked) { 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 } /* ================================== @@ -657,6 +716,21 @@ int transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { 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)); + //TODO printf("%s() Unlock type= %d\n", __func__, TYPE(header)); + } + ptr=ptr->next; + } +#endif return 0; } @@ -670,7 +744,6 @@ int transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { **/ #ifdef STMSTATS void getTotalAbortCount(int start, int stop, void *startptr, void *checkptr, char type) { - printf("Inside %s()\n", __func__); int i; if(type == 'w') { int isFirstTime = 0; @@ -707,8 +780,44 @@ void getTotalAbortCount(int start, int stop, void *startptr, void *checkptr, cha } } } -#else -void getTotalAbortCount(int start, int stop, void *startptr, void *checkptr, char type) { - return; + +/** + * needLock + * params: Object header + * Locks an object that causes aborts + **/ +void needLock(objheader_t *header) { + if(pthread_mutex_trylock(&(header->objlock))) { //busy and failed to get locked + trec.blocked = 1; //set blocked flag + while(header->trec == NULL) { //retry + ; + } + if(header->trec->blocked == 1) { //ignore locking + return; + } else { //lock that blocks + pthread_mutex_lock(&(header->objlock)); + //TODO printf("%s() Got lock on type= %d in second try\n", __func__, TYPE(header)); + /* Reset blocked field */ + trec.blocked = 0; + /* Set trec */ + header->trec = &trec; + } + } else { //acquired lock + //TODO printf("%s() Got lock on type= %d in first try\n", __func__, TYPE(header)); + /* Reset blocked field */ + trec.blocked = 0; + /* Set trec */ + header->trec = &trec; + } + /* 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 diff --git a/Robust/src/Runtime/STM/tm.h b/Robust/src/Runtime/STM/tm.h index 1fe0380c..a1668206 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -35,11 +35,19 @@ #ifdef COMPILER #include "structdefs.h" + +typedef struct threadrec { + int blocked; +} threadrec_t; + typedef struct objheader { unsigned int version; - unsigned int lock; - int abortCount; - int accessCount; + unsigned int lock; /* reader and writer lock for object header */ + int abortCount; /* track how many times does this object cause abort */ + int accessCount; /* track how many times is this object accessed */ + threadrec_t *trec; /* some thread that locked this object */ + int riskyflag; /* track how risky is the object */ + pthread_mutex_t objlock; /* lock this object */ } objheader_t; #define OID(x) \ @@ -80,6 +88,8 @@ typedef struct objheader { * ================================ */ #define DEFAULT_OBJ_STORE_SIZE 1048510 //1MB +#define MAXABORTS 2 +#define NEED_LOCK_THRESHOLD 0.020000 #define OSUSED(x) (((unsigned INTPTR)(x)->top)-((unsigned INTPTR) (x+1))) #define OSFREE(x) ((x)->size-OSUSED(x)) #define TRANSREAD(x,y) { \ @@ -115,6 +125,10 @@ struct objlist { extern __thread struct objlist * newobjs; extern __thread objstr_t *t_cache; extern __thread objstr_t *t_reserve; +#ifdef STMSTATS +extern __thread threadrec_t trec; +extern __thread struct objlist * lockedobjs; +#endif /*********************************** @@ -152,6 +166,8 @@ int alttraverseCache(); int transAbortProcess(void **, int); int transCommmitProcess(void **, int); void randomdelay(int); +#ifdef STMSTATS void getTotalAbortCount(int, int, void *, void *, char); - +void needLock(objheader_t *); +#endif #endif diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c index a565825d..42fc413e 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -302,6 +302,9 @@ void collect(struct garbagelist * stackptr) { if (c_table!=NULL) { fixtable(&c_table, &c_list, &c_structs, c_size); fixobjlist(newobjs); +#ifdef STMSTATS + fixobjlist(lockedobjs); +#endif } memorybase=NULL; #endif @@ -332,6 +335,9 @@ void collect(struct garbagelist * stackptr) { if ((*listptr->tc_table)!=NULL) { fixtable(listptr->tc_table, listptr->tc_list, listptr->tc_structs, listptr->tc_size); fixobjlist(listptr->objlist); +#ifdef STMSTATS + fixobjlist(listptr->lockedlist); +#endif } *(listptr->base)=NULL; #endif @@ -604,6 +610,9 @@ struct listitem * stopforgc(struct garbagelist * ptr) { litem->tc_list=&c_list; litem->tc_structs=&c_structs; litem->objlist=newobjs; +#ifdef STMSTATS + litem->lockedlist=lockedobjs; +#endif litem->base=&memorybase; #endif litem->prev=NULL; diff --git a/Robust/src/Runtime/garbage.h b/Robust/src/Runtime/garbage.h index d402ab92..aa3451e3 100644 --- a/Robust/src/Runtime/garbage.h +++ b/Robust/src/Runtime/garbage.h @@ -22,6 +22,9 @@ struct listitem { chashlistnode_t **tc_table; chashlistnode_t **tc_list; struct objlist * objlist; +#ifdef STMSTATS + struct objlist * lockedlist; +#endif char **base; #endif }; diff --git a/Robust/src/Runtime/thread.c b/Robust/src/Runtime/thread.c index 24eb70cd..3f3a5898 100644 --- a/Robust/src/Runtime/thread.c +++ b/Robust/src/Runtime/thread.c @@ -114,6 +114,10 @@ void initializethreads() { t_cache = objstrCreate(1048576); t_reserve=NULL; t_chashCreate(CHASH_SIZE, CLOADFACTOR); +#ifdef STMSTATS + trec.blocked = 0; + lockedobjs=calloc(1, sizeof(struct objlist)); +#endif #endif } @@ -125,6 +129,10 @@ void initthread(struct ___Thread___ * ___this___) { ___Thread______staticStart____L___Thread___((struct ___Thread______staticStart____L___Thread____params *)p); #else newobjs=calloc(1, sizeof(struct objlist)); +#ifdef STMSTATS + trec.blocked = 0; + lockedobjs=calloc(1, sizeof(struct objlist)); +#endif t_cache = objstrCreate(1048576); t_reserve=NULL; t_chashCreate(CHASH_SIZE, CLOADFACTOR); @@ -133,6 +141,9 @@ void initthread(struct ___Thread___ * ___this___) { objstrDelete(t_reserve); t_chashDelete(); free(newobjs); +#ifdef STMSTATS + free(lockedobjs); +#endif #endif ___this___=(struct ___Thread___ *) p[2]; #else