fix bugs, speedup
authorbdemsky <bdemsky>
Mon, 13 Apr 2009 22:58:08 +0000 (22:58 +0000)
committerbdemsky <bdemsky>
Mon, 13 Apr 2009 22:58:08 +0000 (22:58 +0000)
Robust/src/Runtime/STM/stm.c
Robust/src/Runtime/STM/stmlookup.c
Robust/src/Runtime/STM/stmlookup.h
Robust/src/Runtime/STM/tm.h
Robust/src/Runtime/garbage.c
Robust/src/Runtime/garbage.h

index 1c3a01476542bc79cc573db778679298defb88a6..84a0ab644e326e71cbc329a1ba0b9873b38be0ca 100644 (file)
@@ -220,7 +220,11 @@ int transCommit() {
 #endif
   do {
     /* Look through all the objects in the transaction hash table */
-    int finalResponse = traverseCache();
+    int finalResponse;
+    if (c_numelements<(c_size>>3))
+      finalResponse= alttraverseCache();
+    else
+      finalResponse= traverseCache();
     if(finalResponse == TRANS_ABORT) {
 #ifdef TRANSSTATS
       numTransAbort++;
@@ -351,6 +355,91 @@ int traverseCache() {
   }
 }
 
+/* ==================================================
+ * traverseCache
+ * - 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];
+  void * wrlocked[200];
+  int softabort=0;
+  int i;
+  void ** oidrdlocked;
+  void ** oidwrlocked;
+  if (c_numelements<200) {
+    oidrdlocked=rdlocked;
+    oidwrlocked=wrlocked;
+  } else {
+    int size=c_numelements*sizeof(void*);
+    oidrdlocked=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];
+    
+    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->lnext;
+  }
+  
+  /* Decide the final response */
+  if (softabort) {
+    transAbortProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked);
+    return TRANS_SOFT_ABORT;
+  } else {
+    transCommitProcess(oidrdlocked, &numoidrdlocked, oidwrlocked, &numoidwrlocked);
+    return TRANS_COMMIT;
+  }
+}
+
 
 /* ==================================
  * transAbortProcess
index f9537c53f99d38ab4eed622843d1ccb2f394b3a5..26da7e5bf75d1519116e8ef7e8e30cbf1555084a 100644 (file)
@@ -2,6 +2,7 @@
 #include "strings.h"
 
 __thread chashlistnode_t *c_table;
+__thread chashlistnode_t *c_list;
 __thread unsigned int c_size;
 __thread unsigned INTPTR c_mask;
 __thread unsigned int c_numelements;
@@ -22,94 +23,39 @@ void t_chashCreate(unsigned int size, double loadfactor) {
   c_threshold=size*loadfactor;
   c_mask = (size << 3)-1;
   c_numelements = 0; // Initial number of elements in the hash
+  c_list=NULL;
 }
 
 void t_chashreset() {
   chashlistnode_t *ptr = c_table;
   int i;
-  for(i=0 ; i<c_size ; i++) {
-    chashlistnode_t * curr = ptr[i].next;
-    while(curr!=NULL) {
-      chashlistnode_t * next = curr->next;
-      free(curr);
-      curr=next;
+  if (c_numelements<(c_size>>3)) {
+    chashlistnode_t *top=&ptr[c_size];
+    chashlistnode_t *tmpptr=c_list;
+    while(tmpptr!=NULL) {
+      chashlistnode_t *next=tmpptr->lnext;
+      if (tmpptr>=ptr&&tmpptr<top) {
+       //zero in list
+       tmpptr->key=0;
+       tmpptr->next=NULL;
+      } else {
+       free(tmpptr);
+      }
+      tmpptr=next;
+    }
+  } else {
+    for(i=0 ; i<c_size ; i++) {
+      chashlistnode_t * curr = ptr[i].next;
+      while(curr!=NULL) {
+       chashlistnode_t * next = curr->next;
+       free(curr);
+       curr=next;
+      }
     }
+    bzero(c_table, sizeof(chashlistnode_t)*c_size);
   }
   c_numelements = 0;
-  bzero(c_table, sizeof(chashlistnode_t)*c_size);
-}
-
-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, void * key) {
-  return (((unsigned INTPTR) key) & (table->mask))>>3; //throw away low order bit
-}
-
-//Store objects and their pointers into hash
-void chashInsert(chashtable_t *table, void * key, void *val) {
-  chashlistnode_t *ptr;
-
-  if(table->numelements > (table->threshold)) {
-    //Resize
-    unsigned int newsize = table->size << 1;
-    chashResize(table,newsize);
-  }
-
-  ptr = &table->table[(((unsigned INTPTR)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, void * key) {
-  //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
-  chashlistnode_t *node = &table->table[(((unsigned INTPTR)key) & table->mask)>>3];
-
-  do {
-    if(node->key == key) {
-      return node->val;
-    }
-    node = node->next;
-  } while(node != NULL);
-
-  return NULL;
+  c_list=NULL;
 }
 
 //Store objects and their pointers into hash
@@ -129,12 +75,16 @@ void t_chashInsert(void * key, void *val) {
   if(ptr->key==0) {
     ptr->key=key;
     ptr->val=val;
+    ptr->lnext=c_list;
+    c_list=ptr;
   } 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;
+    node->lnext=c_list;
+    c_list=node;
   }
 }
 
@@ -152,112 +102,6 @@ INLINE void * t_chashSearch(void * key) {
 
   return NULL;
 }
-
-unsigned int chashRemove(chashtable_t *table, void * key) {
-  return chashRemove2(table, key)==NULL;
-
-}
-
-void * chashRemove2(chashtable_t *table, void * 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
-      void * 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 = (((unsigned INTPTR)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;
@@ -267,6 +111,7 @@ unsigned int t_chashResize(unsigned int newsize) {
   
   ptr = c_table;
   oldsize = c_size;
+  c_list=NULL;
 
   if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
     printf("Calloc error %s %d\n", __FILE__, __LINE__);
@@ -295,6 +140,8 @@ unsigned int t_chashResize(unsigned int newsize) {
       if(tmp->key == 0) {
        tmp->key = curr->key;
        tmp->val = curr->val;
+       tmp->lnext=c_list;
+       c_list=tmp;
        if (!isfirst) {
          free(curr);
        }
@@ -311,6 +158,8 @@ unsigned int t_chashResize(unsigned int newsize) {
       else {
        curr->next=tmp->next;
        tmp->next=curr;
+       curr->lnext=c_list;
+       c_list=curr;
       }
 
       isfirst = 0;
@@ -322,23 +171,6 @@ unsigned int t_chashResize(unsigned int newsize) {
   return 0;
 }
 
-//Delete the entire hash table
-void chashDelete(chashtable_t *ctable) {
-  int i;
-  chashlistnode_t *ptr = ctable->table;
-
-  for(i=0 ; i<ctable->size ; 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;
@@ -354,4 +186,5 @@ void t_chashDelete() {
   }
   free(ptr);
   c_table=NULL;
+  c_list=NULL;
 }
index e75447483de6e223e8bfb9f6f165db3502f47036..476716e177d46160018578a0cead7667aec13879 100644 (file)
@@ -22,6 +22,7 @@ typedef struct chashlistnode {
   void * key;
   void * val;     //this can be cast to another type or used to point to a larger structure
   struct chashlistnode *next;
+  struct chashlistnode *lnext;
 } chashlistnode_t;
 
 typedef struct chashtable {
@@ -41,17 +42,9 @@ unsigned int t_chashResize(unsigned int newsize);
 void t_chashDelete();
 void t_chashreset();
 
-/* Prototypes for hash*/
-chashtable_t *chashCreate(unsigned int size, double loadfactor);
-void chashInsert(chashtable_t *table, void * key, void *val);
-void *chashSearch(chashtable_t *table, void * key); //returns val, NULL if not found
-unsigned int chashRemove(chashtable_t *table, void * key); //returns -1 if not found
-void * chashRemove2(chashtable_t *table, void * 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 chashlistnode_t *c_list;
 extern __thread unsigned int c_size;
 extern __thread unsigned INTPTR c_mask;
 extern __thread unsigned int c_numelements;
index 3227d5112affe1fb46bf3047f22cf9b9278c37f5..6910348bfd77e86dee834647b5743e08fc7eb976 100644 (file)
@@ -145,6 +145,7 @@ void *objstrAlloc(unsigned int size);
 __attribute__((pure)) void *transRead(void * oid);
 int transCommit();
 int traverseCache();
+int alttraverseCache();
 int transAbortProcess(void **, int *, void **, int *);
 int transCommmitProcess(void **, int *, void **, int *);
 void randomdelay();
index fb6c161ffad5d2ad28b1d7cdf43cbcb880c2e0bb..3fadff449c8380a1c4f0d799bc6e197f7cb13e59 100644 (file)
@@ -147,7 +147,7 @@ void fixobjlist(struct objlist * ptr) {
   }
 }
 
-void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) {
+void fixtable(chashlistnode_t ** tc_table, chashlistnode_t **tc_list, unsigned int tc_size) {
   unsigned int mask=(tc_size<<3)-1;
   chashlistnode_t *node=calloc(tc_size, sizeof(chashlistnode_t));
   chashlistnode_t *ptr=*tc_table;
@@ -155,6 +155,7 @@ void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) {
   unsigned int i;
   unsigned int index;
   int isfirst;
+  chashlistnode_t *newlist=NULL;
   for(i=0;i<tc_size;i++) {
     curr=&ptr[i];
     isfirst=1;
@@ -207,6 +208,8 @@ void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) {
       if(tmp->key == 0) {
        tmp->key = curr->key;
        tmp->val = curr->val;
+       tmp->lnext=newlist;
+       newlist=tmp;
        if (!isfirst) {
          free(curr);
        }
@@ -215,8 +218,12 @@ void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) {
        newnode->key = curr->key;
        newnode->val = curr->val;
        newnode->next = tmp->next;
+       newnode->lnext=newlist;
+       newlist=newnode;
        tmp->next=newnode;
       } else {
+       curr->lnext=newlist;
+       newlist=curr;
        curr->next=tmp->next;
        tmp->next=curr;
       }
@@ -226,6 +233,7 @@ void fixtable(chashlistnode_t ** tc_table, unsigned int tc_size) {
   }
   free(ptr);
   (*tc_table)=node;
+  (*tc_list)=newlist;
 }
 #endif
 
@@ -284,8 +292,8 @@ void collect(struct garbagelist * stackptr) {
 
 #ifdef STM
   if (c_table!=NULL) {
-      fixtable(&c_table, c_size);
-      fixobjlist(newobjs);
+    fixtable(&c_table, &c_list, c_size);
+    fixobjlist(newobjs);
   }
   memorybase=NULL;
 #endif
@@ -314,7 +322,7 @@ void collect(struct garbagelist * stackptr) {
 #endif
 #ifdef STM
     if ((*listptr->tc_table)!=NULL) {
-      fixtable(listptr->tc_table, listptr->tc_size);
+      fixtable(listptr->tc_table, listptr->tc_list, listptr->tc_size);
       fixobjlist(listptr->objlist);
     }
     *(listptr->base)=NULL;
@@ -585,6 +593,7 @@ struct listitem * stopforgc(struct garbagelist * ptr) {
 #ifdef STM
   litem->tc_size=c_size;
   litem->tc_table=&c_table;
+  litem->tc_list=&c_list;
   litem->objlist=newobjs;
   litem->base=&memorybase;
 #endif
index 7a9dc9c75462a134322ba6b124b22145a1cba6c4..597734edcbcb3c53f018b39048afff65a1824442 100644 (file)
@@ -19,6 +19,7 @@ struct listitem {
 #ifdef STM
   unsigned int tc_size;
   chashlistnode_t **tc_table;
+  chashlistnode_t **tc_list;
   struct objlist * objlist;
   char **base;
 #endif
@@ -40,5 +41,5 @@ int gc_createcopy(void * orig, void **);
 void * mygcmalloc(struct garbagelist * ptr, int size);
 #endif
 #ifdef STM
-void fixtable(chashlistnode_t **, unsigned int);
+void fixtable(chashlistnode_t **, chashlistnode_t **, unsigned int);
 #endif