From: bdemsky Date: Wed, 8 Apr 2009 08:51:09 +0000 (+0000) Subject: hack stuff not to put new objects in lookup table...trying to make object creation... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dc822b69d81af5c29df955dcaf75c348eb25f655;p=IRC.git hack stuff not to put new objects in lookup table...trying to make object creation inside of transactions even cheaper --- diff --git a/Robust/src/Benchmarks/SingleTM/RainForest/RainForest.java b/Robust/src/Benchmarks/SingleTM/RainForest/RainForest.java index f185a92f..7e3adc43 100644 --- a/Robust/src/Benchmarks/SingleTM/RainForest/RainForest.java +++ b/Robust/src/Benchmarks/SingleTM/RainForest/RainForest.java @@ -53,9 +53,7 @@ public class RainForest extends Thread { //Barrier for synchronizing moves Barrier barr; int id; - atomic { - id = threadid; - } + id = threadid; barr = new Barrier("127.0.0.1"); Random rand = new Random(id); @@ -123,43 +121,37 @@ public class RainForest extends Thread { // Init land and place rocks in boundaries GameMap[][] world; - atomic { - mybarr = new BarrierServer(numThreads); - world = new GameMap[ROW][COLUMN]; - int i, j; - for (i = 0; i < ROW; i++) { - for (j = 0; j < COLUMN; j++) { - world[i][j] = new GameMap(); - if (j == 0 || j == COLUMN-1) { - RockType r = new RockType(); - world[i][j].putRock(r); - } - if (i == 0 || i == ROW-1) { - RockType r = new RockType(); - world[i][j].putRock(r); - } + mybarr = new BarrierServer(numThreads); + world = new GameMap[ROW][COLUMN]; + + for (int i = 0; i < ROW; i++) { + for (int j = 0; j < COLUMN; j++) { + world[i][j] = new GameMap(); + if (j == 0 || j == COLUMN-1) { + RockType r = new RockType(); + world[i][j].putRock(r); + } + if (i == 0 || i == ROW-1) { + RockType r = new RockType(); + world[i][j].putRock(r); + } } - } } mybarr.start(); /* Set up threads */ RainForest[] rf; - atomic { - rf = new RainForest[numThreads]; - for(int i=0; i tmp1${MAINCLASS}.java diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index 2c9bae70..0074741d 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -14,6 +14,7 @@ #include "garbage.h" /* Thread transaction variables */ __thread objstr_t *t_cache; +__thread struct objlist * newobjs; #ifdef TRANSSTATS int numTransCommit = 0; @@ -78,10 +79,19 @@ void transStart() { objheader_t *transCreateObj(void * ptr, unsigned int size) { objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size)); objheader_t *retval=&tmp[1]; - initdsmlocks(&tmp->lock); + tmp->lock=RW_LOCK_BIAS; tmp->version = 1; STATUS(tmp)=NEW; - t_chashInsert((unsigned int) retval, retval); + // don't insert into table + if (newobjs->offsetobjs[newobjs->offset++]=retval; + } else { + struct objlist *tmp=malloc(sizeof(struct objlist)); + tmp->next=newobjs; + tmp->objs[0]=retval; + tmp->offset=1; + newobjs=tmp; + } return retval; //want space after object header } @@ -145,6 +155,10 @@ __attribute__((pure)) void *transRead(void * oid) { objheader_t *objcopy; int size; + //quick case for new objects + if (((struct ___Object___ *)oid)->___objstatus___ & NEW) + return oid; + /* Read from the main heap */ objheader_t *header = (objheader_t *)(((char *)oid) - sizeof(objheader_t)); if(read_trylock(&header->lock)) { //Can further acquire read locks @@ -160,6 +174,17 @@ __attribute__((pure)) void *transRead(void * oid) { } } +void freenewobjs() { + struct objlist *ptr=newobjs; + while(ptr->next!=NULL) { + struct objlist *tmp=ptr->next; + free(ptr); + ptr=tmp; + } + ptr->offset=0; + newobjs=ptr; +} + /* ================================================================ * transCommit * - This function initiates the transaction commit process @@ -175,6 +200,7 @@ int transCommit() { #ifdef TRANSSTATS numTransAbort++; #endif + freenewobjs(); objstrDelete(t_cache); t_chashDelete(); return TRANS_ABORT; @@ -183,6 +209,7 @@ int transCommit() { #ifdef TRANSSTATS numTransCommit++; #endif + freenewobjs(); objstrDelete(t_cache); t_chashDelete(); return 0; @@ -229,9 +256,7 @@ int traverseCache() { unsigned int version = headeraddr->version; objheader_t *header=(objheader_t *) (((char *)curr->key)-sizeof(objheader_t)); - if(STATUS(headeraddr) & NEW) { - STATUS(headeraddr)=0; - } else if(STATUS(headeraddr) & DIRTY) { + 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 */ @@ -325,7 +350,16 @@ int transCommitProcess(unsigned int *oidrdlocked, int *numoidrdlocked, 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 */ diff --git a/Robust/src/Runtime/STM/stmlookup.c b/Robust/src/Runtime/STM/stmlookup.c new file mode 100644 index 00000000..1626d271 --- /dev/null +++ b/Robust/src/Runtime/STM/stmlookup.c @@ -0,0 +1,341 @@ +#include "stmlookup.h" + +__thread chashlistnode_t *c_table; +__thread unsigned int c_size; +__thread unsigned int c_mask; +__thread unsigned int c_numelements; +__thread unsigned int c_threshold; +__thread double c_loadfactor; + +void t_chashCreate(unsigned int size, double loadfactor) { + chashtable_t *ctable; + chashlistnode_t *nodes; + int i; + + // Allocate space for the hash table + + + c_table = calloc(size, sizeof(chashlistnode_t)); + c_loadfactor = loadfactor; + c_size = size; + c_threshold=size*loadfactor; + c_mask = (size << 3)-1; + c_numelements = 0; // Initial number of elements in the hash +} + +chashtable_t *chashCreate(unsigned int size, double loadfactor) { + chashtable_t *ctable; + chashlistnode_t *nodes; + int i; + + if((ctable = calloc(1, sizeof(chashtable_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return NULL; + } + + // Allocate space for the hash table + if((nodes = calloc(size, sizeof(chashlistnode_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + free(ctable); + return NULL; + } + + ctable->table = nodes; + ctable->loadfactor = loadfactor; + ctable->size = size; + ctable->threshold=size*loadfactor; + ctable->mask = (size << 3)-1; + ctable->numelements = 0; // Initial number of elements in the hash + + + return ctable; +} + +//Finds the right bin in the hash table +static INLINE unsigned int chashFunction(chashtable_t *table, unsigned int key) { + return ( key & (table->mask))>>3; //throw away low order bit +} + +//Store objects and their pointers into hash +void chashInsert(chashtable_t *table, unsigned int key, void *val) { + chashlistnode_t *ptr; + + if(table->numelements > (table->threshold)) { + //Resize + unsigned int newsize = table->size << 1; + chashResize(table,newsize); + } + + ptr = &table->table[(key&table->mask)>>3]; + table->numelements++; + + if(ptr->key==0) { + ptr->key=key; + ptr->val=val; + } else { // Insert in the beginning of linked list + chashlistnode_t * node = calloc(1, sizeof(chashlistnode_t)); + node->key = key; + node->val = val; + node->next = ptr->next; + ptr->next=node; + } +} + +// Search for an address for a given oid +INLINE void * chashSearch(chashtable_t *table, unsigned int key) { + //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE + chashlistnode_t *node = &table->table[(key & table->mask)>>3]; + + do { + if(node->key == key) { + return node->val; + } + node = node->next; + } while(node != NULL); + + return NULL; +} + +//Store objects and their pointers into hash +void t_chashInsert(unsigned int key, void *val) { + chashlistnode_t *ptr; + + + if(c_numelements > (c_threshold)) { + //Resize + unsigned int newsize = c_size << 1; + t_chashResize(newsize); + } + + ptr = &c_table[(key&c_mask)>>3]; + c_numelements++; + + if(ptr->key==0) { + ptr->key=key; + ptr->val=val; + } else { // Insert in the beginning of linked list + chashlistnode_t * node = calloc(1, sizeof(chashlistnode_t)); + node->key = key; + node->val = val; + node->next = ptr->next; + ptr->next=node; + } +} + +// Search for an address for a given oid +INLINE void * t_chashSearch(unsigned int key) { + //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE + chashlistnode_t *node = &c_table[(key & c_mask)>>3]; + + do { + if(node->key == key) { + return node->val; + } + node = node->next; + } while(node != NULL); + + return NULL; +} + +unsigned int chashRemove(chashtable_t *table, unsigned int key) { + return chashRemove2(table, key)==NULL; + +} + +void * chashRemove2(chashtable_t *table, unsigned int key) { + int index; + chashlistnode_t *curr, *prev; + chashlistnode_t *ptr, *node; + void *value; + + ptr = table->table; + index = chashFunction(table,key); + curr = &ptr[index]; + + for (; curr != NULL; curr = curr->next) { + if (curr->key == key) { // Find a match in the hash table + table->numelements--; // Decrement the number of elements in the global hashtable + if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of chashlistnode_t + curr->key = 0; + value=curr->val; + curr->val = NULL; + } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of chashlistnode_t connected + curr->key = curr->next->key; + value=curr->val; + curr->val = curr->next->val; + node = curr->next; + curr->next = curr->next->next; + free(node); + } else { // Regular delete from linked listed + prev->next = curr->next; + value=curr->val; + free(curr); + } + return value; + } + prev = curr; + } + return NULL; +} + +unsigned int chashResize(chashtable_t *table, 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 = table->table; + oldsize = table->size; + + if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return 1; + } + + table->table = node; //Update the global hashtable upon resize() + table->size = newsize; + table->threshold = newsize * table->loadfactor; + mask=table->mask = (newsize << 3)-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 + unsigned int 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 + } + next = curr->next; + index = (key & mask) >>3; + tmp=&node[index]; + // Insert into the new table + if(tmp->key == 0) { + tmp->key = curr->key; + tmp->val = curr->val; + if (!isfirst) { + free(curr); + } + }/* + 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; + } + + isfirst = 0; + curr = next; + } while(curr!=NULL); + } + + free(ptr); //Free the memory of the old hash table + return 0; +} + +unsigned int 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 = c_table; + oldsize = c_size; + + if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return 1; + } + + c_table = node; //Update the global hashtable upon resize() + c_size = newsize; + c_threshold = newsize * c_loadfactor; + mask=c_mask = (newsize << 3)-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 + unsigned int 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 + } + next = curr->next; + index = (key & mask) >>3; + tmp=&node[index]; + // Insert into the new table + if(tmp->key == 0) { + tmp->key = curr->key; + tmp->val = curr->val; + if (!isfirst) { + free(curr); + } + }/* + 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; + } + + 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 chashDelete(chashtable_t *ctable) { + int i; + chashlistnode_t *ptr = ctable->table; + + for(i=0 ; isize ; i++) { + chashlistnode_t * curr = ptr[i].next; + while(curr!=NULL) { + chashlistnode_t * next = curr->next; + free(curr); + curr=next; + } + } + free(ptr); + free(ctable); +} + +//Delete the entire hash table +void t_chashDelete() { + int i; + chashlistnode_t *ptr = c_table; + + for(i=0 ; inext; + free(curr); + curr=next; + } + } + free(ptr); + c_table=NULL; +} diff --git a/Robust/src/Runtime/STM/stmlookup.h b/Robust/src/Runtime/STM/stmlookup.h new file mode 100644 index 00000000..2382208e --- /dev/null +++ b/Robust/src/Runtime/STM/stmlookup.h @@ -0,0 +1,53 @@ +#ifndef _CLOOKUP_H_ +#define _CLOOKUP_H_ + +#include +#include + +#define CLOADFACTOR 0.25 +#define CHASH_SIZE 1024 + +#define INLINE inline __attribute__((always_inline)) + + +typedef struct chashlistnode { + unsigned int key; + void *val; //this can be cast to another type or used to point to a larger structure + struct chashlistnode *next; +} chashlistnode_t; + +typedef struct chashtable { + chashlistnode_t *table; // points to beginning of hash table + unsigned int size; + unsigned int mask; + unsigned int numelements; + unsigned int threshold; + double loadfactor; +} chashtable_t; + + +void t_chashCreate(unsigned int size, double loadfactor); +void t_chashInsert(unsigned int key, void *val); +void * t_chashSearch(unsigned int key); +unsigned int t_chashResize(unsigned int newsize); +void t_chashDelete(); + +/* Prototypes for hash*/ +chashtable_t *chashCreate(unsigned int size, double loadfactor); +static unsigned int chashFunction(chashtable_t *table, unsigned int key); +void chashInsert(chashtable_t *table, unsigned int key, void *val); +void *chashSearch(chashtable_t *table, unsigned int key); //returns val, NULL if not found +unsigned int chashRemove(chashtable_t *table, unsigned int key); //returns -1 if not found +void * chashRemove2(chashtable_t *table, unsigned int key); //returns -1 if not found +unsigned int chashResize(chashtable_t *table, unsigned int newsize); +void chashDelete(chashtable_t *table); +/* end hash */ + +extern __thread chashlistnode_t *c_table; +extern __thread unsigned int c_size; +extern __thread unsigned int c_mask; +extern __thread unsigned int c_numelements; +extern __thread unsigned int c_threshold; +extern __thread double c_loadfactor; + +#endif diff --git a/Robust/src/Runtime/STM/tm.h b/Robust/src/Runtime/STM/tm.h index c5df6447..918cd9f3 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -26,7 +26,7 @@ #include #include #include "threadnotify.h" -#include "clookup.h" +#include "stmlookup.h" #include "dsmlock.h" /* ================================== @@ -52,10 +52,10 @@ typedef struct objheader { ((void*)((((void *) x )!=NULL) ? (*((unsigned int *)&((struct ___Object___ *) x)->___objlocation___)) : 0)) #define STATUS(x) \ - *((unsigned int *) &(((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->___objstatus___)) + *((unsigned int *) &(((struct ___Object___ *)(((char *) x) + sizeof(objheader_t)))->___objstatus___)) #define STATUSPTR(x) \ - ((unsigned int *) &(((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->___objstatus___)) + ((unsigned int *) &(((struct ___Object___ *)(((char *) x) + sizeof(objheader_t)))->___objstatus___)) #define TYPE(x) \ ((struct ___Object___ *)((unsigned int) x + sizeof(objheader_t)))->type @@ -89,7 +89,7 @@ typedef struct objheader { unsigned int inputvalue;\ if ((inputvalue=(unsigned int)y)==0) x=NULL;\ else { \ -chashlistnode_t * cnodetmp=&c_table[(inputvalue&c_mask)>>1]; \ +chashlistnode_t * cnodetmp=&c_table[(inputvalue&c_mask)>>3]; \ do { \ if (cnodetmp->key==inputvalue) {x=(void *)cnodetmp->val;break;} \ cnodetmp=cnodetmp->next;\ @@ -108,6 +108,15 @@ typedef struct objstr { struct objstr *prev; } objstr_t; +#define MAXOBJLIST 512 +struct objlist { + int offset; + void * objs[MAXOBJLIST]; + struct objlist * next; +}; + +extern __thread struct objlist * newobjs; + typedef struct newObjCreated { unsigned int numcreated; unsigned int *oidcreated; diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c index 647cd36c..0b8e8465 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -137,8 +137,18 @@ void * dequeue() { } #ifdef STM +void fixobjlist(struct objlist * ptr) { + while(ptr!=NULL) { + int i; + for(i=0;ioffset;i++) { + SENQUEUE(ptr->objs[i], ptr->objs[i]); + } + ptr=ptr->next; + } +} + void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) { - unsigned int mask=(tc_size<<1)-1; + unsigned int mask=(tc_size<<3)-1; chashlistnode_t *node=calloc(tc_size, sizeof(chashlistnode_t)); chashlistnode_t *ptr=*tc_table; chashlistnode_t *curr; @@ -189,7 +199,7 @@ void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) { } next = curr->next; - index = (((unsigned int)key) & mask) >>1; + index = (((unsigned int)key) & mask) >>3; curr->key=(unsigned int)key; tmp=&node[index]; @@ -268,8 +278,10 @@ void collect(struct garbagelist * stackptr) { #endif #ifdef STM - if (c_table!=NULL) + if (c_table!=NULL) { fixtable(&c_table, c_size); + fixobjlist(newobjs); + } #endif /* Check current stack */ @@ -295,8 +307,10 @@ void collect(struct garbagelist * stackptr) { ENQUEUE(orig, listptr->locklist); #endif #ifdef STM - if ((*listptr->tc_table)!=NULL) + if ((*listptr->tc_table)!=NULL) { fixtable(listptr->tc_table, listptr->tc_size); + fixobjlist(listptr->objlist); + } #endif stackptr=listptr->stackptr; listptr=listptr->next; @@ -565,6 +579,7 @@ struct listitem * stopforgc(struct garbagelist * ptr) { #ifdef STM litem->tc_size=c_size; litem->tc_table=&c_table; + litem->objlist=newobjs; #endif litem->prev=NULL; pthread_mutex_lock(&gclistlock); @@ -608,7 +623,7 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) { #endif ptr=curr_heapptr; if ((size&7)!=0) - size+=(8-(size%8)); + size=(size&~7)+8; curr_heapptr+=size; if (curr_heapptr>curr_heapgcpoint) { if (curr_heapbase==0) { diff --git a/Robust/src/Runtime/garbage.h b/Robust/src/Runtime/garbage.h index 7fbec22e..7d7417ab 100644 --- a/Robust/src/Runtime/garbage.h +++ b/Robust/src/Runtime/garbage.h @@ -19,6 +19,7 @@ struct listitem { #ifdef STM unsigned int tc_size; chashlistnode_t **tc_table; + struct objlist * objlist; #endif }; diff --git a/Robust/src/Runtime/thread.c b/Robust/src/Runtime/thread.c index 5fe7da5c..01955417 100644 --- a/Robust/src/Runtime/thread.c +++ b/Robust/src/Runtime/thread.c @@ -114,7 +114,9 @@ void initthread(struct ___Thread___ * ___this___) { #ifdef THREADS ___Thread______staticStart____L___Thread___((struct ___Thread______staticStart____L___Thread____params *)p); #else + newobjs=calloc(1, sizeof(struct objlist)); ___Thread____NN____staticStart____L___Thread___((struct ___Thread____NN____staticStart____L___Thread____params *)p); + free(newobjs); #endif ___this___=(struct ___Thread___ *) p[2]; #else diff --git a/Robust/src/buildscript b/Robust/src/buildscript index 193f55e8..95682055 100755 --- a/Robust/src/buildscript +++ b/Robust/src/buildscript @@ -484,7 +484,7 @@ fi if $SINGLETM then EXTRAOPTIONS="$EXTRAOPTIONS -lpthread -DCOMPILER -I$DSMRUNTIME" -FILES="$FILES $DSMRUNTIME/dsmlock.c $DSMRUNTIME/singleTMCommit.c $DSMRUNTIME/clookup.c $ROBUSTROOT/Runtime/thread.c" +FILES="$FILES $DSMRUNTIME/dsmlock.c $DSMRUNTIME/singleTMCommit.c $DSMRUNTIME/stmlookup.c $ROBUSTROOT/Runtime/thread.c" fi if $ABORTREADERS