add new features...they don't break the build, but need to check if they work...
[IRC.git] / Robust / src / Runtime / STM / stmlookup.c
index ab961244519f5d515d7e13057cccf52294ea4e63..42ce0d91d16991b4202677327c9e36487dbffbb2 100644 (file)
@@ -10,54 +10,244 @@ __thread unsigned int c_threshold;
 __thread double c_loadfactor;
 __thread cliststruct_t *c_structs;
 
+#ifdef READSET
+__thread rdchashlistnode_t *rd_c_table;
+__thread rdchashlistnode_t *rd_c_list;
+__thread unsigned int rd_c_size;
+__thread unsigned INTPTR rd_c_mask;
+__thread unsigned int rd_c_numelements;
+__thread unsigned int rd_c_threshold;
+__thread double rd_c_loadfactor;
+__thread rdcliststruct_t *rd_c_structs;
+
+void rd_t_chashCreate(unsigned int size, double loadfactor) {
+  chashtable_t *ctable;
+  chashlistnode_t *nodes;
+  int i;
+
+  // Allocate space for the hash table
+  rd_c_table = calloc(size, sizeof(rdchashlistnode_t));
+  rd_c_loadfactor = loadfactor;
+  rd_c_size = size;
+  rd_c_threshold=size*loadfactor;
+  rd_c_mask = (size << 4)-1;
+  rd_c_structs=calloc(1, sizeof(rdcliststruct_t));
+  rd_c_numelements = 0; // Initial number of elements in the hash
+  rd_c_list=NULL;
+}
+
+void rd_t_chashreset() {
+  rdchashlistnode_t *ptr = rd_c_table;
+  int i;
+
+  if (rd_c_numelements<(rd_c_size>>4)) {
+    rdchashlistnode_t *top=&ptr[rd_c_size];
+    rdchashlistnode_t *tmpptr=rd_c_list;
+    while(tmpptr!=NULL) {
+      rdchashlistnode_t *next=tmpptr->lnext;
+      if (tmpptr>=ptr&&tmpptr<top) {
+       //zero in list
+       tmpptr->key=NULL;
+       tmpptr->next=NULL;
+      }
+      tmpptr=next;
+    }
+  } else {
+    bzero(rd_c_table, sizeof(rdchashlistnode_t)*rd_c_size);
+  }
+  while(rd_c_structs->next!=NULL) {
+    rdcliststruct_t *next=rd_c_structs->next;
+    free(rd_c_structs);
+    rd_c_structs=next;
+  }
+  rd_c_structs->num = 0;
+  rd_c_numelements = 0;
+  rd_c_list=NULL;
+}
+
+//Store objects and their pointers into hash
+void rd_t_chashInsertOnce(void * key, unsigned int version) {
+  rdchashlistnode_t *ptr;
+
+  if (key==NULL)
+    return;
+
+  if(rd_c_numelements > (rd_c_threshold)) {
+    //Resize
+    unsigned int newsize = rd_c_size << 1;
+    rd_t_chashResize(newsize);
+  }
+
+  ptr = &rd_c_table[(((unsigned INTPTR)key)&rd_c_mask)>>4];
+
+  if(ptr->key==0) {
+    ptr->key=key;
+    ptr->version=version;
+    ptr->lnext=rd_c_list;
+    rd_c_list=ptr;
+    rd_c_numelements++;
+  } else { // Insert in the beginning of linked list
+    rdchashlistnode_t * node;
+    rdchashlistnode_t *search=ptr;
+    
+    //make sure it isn't here
+    do {
+      if(search->key == key) {
+       return;
+      }
+      search=search->next;
+    } while(search != NULL);
+
+    rd_c_numelements++;    
+    if (rd_c_structs->num<NUMCLIST) {
+      node=&rd_c_structs->array[rd_c_structs->num];
+      rd_c_structs->num++;
+    } else {
+      //get new list
+      rdcliststruct_t *tcl=calloc(1,sizeof(rdcliststruct_t));
+      tcl->next=rd_c_structs;
+      rd_c_structs=tcl;
+      node=&tcl->array[0];
+      tcl->num=1;
+    }
+    node->key = key;
+    node->version = version;
+    node->next = ptr->next;
+    ptr->next=node;
+    node->lnext=rd_c_list;
+    rd_c_list=node;
+  }
+}
+
+unsigned int rd_t_chashResize(unsigned int newsize) {
+  rdchashlistnode_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 = rd_c_table;
+  oldsize = rd_c_size;
+  rd_c_list=NULL;
+
+  if((node = calloc(newsize, sizeof(rdchashlistnode_t))) == NULL) {
+    printf("Calloc error %s %d\n", __FILE__, __LINE__);
+    return 1;
+  }
+
+  rd_c_table = node;          //Update the global hashtable upon resize()
+  rd_c_size = newsize;
+  rd_c_threshold = newsize * rd_c_loadfactor;
+  mask=rd_c_mask = (newsize << 4)-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;
+      rdchashlistnode_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
+      }
+      index = (((unsigned INTPTR)key) & mask) >>4;
+      tmp=&node[index];
+      next = curr->next;
+      // Insert into the new table
+      if(tmp->key == 0) {
+       tmp->key = key;
+       tmp->version = curr->version;
+       tmp->lnext=rd_c_list;
+       rd_c_list=tmp;
+      } /*
+          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;
+       curr->lnext=rd_c_list;
+       rd_c_list=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 rd_t_chashDelete() {
+  int i;
+  rdcliststruct_t *ptr=rd_c_structs;
+  while(ptr!=NULL) {
+    rdcliststruct_t *next=ptr->next;
+    free(ptr);
+    ptr=next;
+  }
+  free(rd_c_table);
+  rd_c_table=NULL;
+  rd_c_structs=NULL;
+  rd_c_list=NULL;
+}
+#endif
+
 #ifdef DELAYCOMP
-__thread chashlistnode_t *dc_c_table;
-__thread chashlistnode_t *dc_c_list;
+__thread dchashlistnode_t *dc_c_table;
+__thread dchashlistnode_t *dc_c_list;
 __thread unsigned int dc_c_size;
 __thread unsigned INTPTR dc_c_mask;
 __thread unsigned int dc_c_numelements;
 __thread unsigned int dc_c_threshold;
 __thread double dc_c_loadfactor;
-__thread cliststruct_t *dc_c_structs;
+__thread dcliststruct_t *dc_c_structs;
 
 void dc_t_chashCreate(unsigned int size, double loadfactor) {
-  chashtable_t *ctable;
-  chashlistnode_t *nodes;
+  dchashlistnode_t *nodes;
   int i;
 
   // Allocate space for the hash table
 
-  dc_c_table = calloc(size, sizeof(chashlistnode_t));
+  dc_c_table = calloc(size, sizeof(dchashlistnode_t));
   dc_c_loadfactor = loadfactor;
   dc_c_size = size;
   dc_c_threshold=size*loadfactor;
   dc_c_mask = (size << 4)-1;
-  dc_c_structs=calloc(1, sizeof(cliststruct_t));
+  dc_c_structs=calloc(1, sizeof(dcliststruct_t));
   dc_c_numelements = 0; // Initial number of elements in the hash
   dc_c_list=NULL;
 }
 
 void dc_t_chashreset() {
-  chashlistnode_t *ptr = dc_c_table;
+  dchashlistnode_t *ptr = dc_c_table;
   int i;
 
   if (dc_c_numelements<(dc_c_size>>4)) {
-    chashlistnode_t *top=&ptr[dc_c_size];
-    chashlistnode_t *tmpptr=dc_c_list;
+    dchashlistnode_t *top=&ptr[dc_c_size];
+    dchashlistnode_t *tmpptr=dc_c_list;
     while(tmpptr!=NULL) {
-      chashlistnode_t *next=tmpptr->lnext;
+      dchashlistnode_t *next=tmpptr->lnext;
       if (tmpptr>=ptr&&tmpptr<top) {
        //zero in list
-       tmpptr->key=0;
+       tmpptr->key=NULL;
        tmpptr->next=NULL;
       }
       tmpptr=next;
     }
   } else {
-    bzero(dc_c_table, sizeof(chashlistnode_t)*dc_c_size);
+    bzero(dc_c_table, sizeof(dchashlistnode_t)*dc_c_size);
   }
   while(dc_c_structs->next!=NULL) {
-    cliststruct_t *next=dc_c_structs->next;
+    dcliststruct_t *next=dc_c_structs->next;
     free(dc_c_structs);
     dc_c_structs=next;
   }
@@ -68,6 +258,119 @@ void dc_t_chashreset() {
 
 //Store objects and their pointers into hash
 void dc_t_chashInsertOnce(void * key, void *val) {
+  dchashlistnode_t *ptr;
+
+  if (key==NULL)
+    return;
+
+  if(dc_c_numelements > (dc_c_threshold)) {
+    //Resize
+    unsigned int newsize = dc_c_size << 1;
+    dc_t_chashResize(newsize);
+  }
+
+  ptr = &dc_c_table[(((unsigned INTPTR)key)&dc_c_mask)>>4];
+
+  if(ptr->key==0) {
+    ptr->key=key;
+    ptr->val=val;
+    ptr->lnext=dc_c_list;
+    dc_c_list=ptr;
+    dc_c_numelements++;
+  } else { // Insert in the beginning of linked list
+    dchashlistnode_t * node;
+    dchashlistnode_t *search=ptr;
+    
+    //make sure it isn't here
+    do {
+      if(search->key == key) {
+       return;
+      }
+      search=search->next;
+    } while(search != NULL);
+
+    dc_c_numelements++;    
+    if (dc_c_structs->num<NUMCLIST) {
+      node=&dc_c_structs->array[dc_c_structs->num];
+      dc_c_structs->num++;
+    } else {
+      //get new list
+      dcliststruct_t *tcl=calloc(1,sizeof(dcliststruct_t));
+      tcl->next=dc_c_structs;
+      dc_c_structs=tcl;
+      node=&tcl->array[0];
+      tcl->num=1;
+    }
+    node->key = key;
+    node->val = val;
+    node->next = ptr->next;
+    ptr->next=node;
+    node->lnext=dc_c_list;
+    dc_c_list=node;
+  }
+}
+
+#ifdef STMARRAY
+//Store objects and their pointers into hash
+void dc_t_chashInsertOnceArray(void * key, unsigned int intkey, void *val) {
+  dchashlistnode_t *ptr;
+
+  if (key==NULL)
+    return;
+
+  if(dc_c_numelements > (dc_c_threshold)) {
+    //Resize
+    unsigned int newsize = dc_c_size << 1;
+    dc_t_chashResize(newsize);
+  }
+
+  ptr = &dc_c_table[(((unsigned INTPTR)key^intkey)&dc_c_mask)>>4];
+
+  if(ptr->key==0) {
+    ptr->key=key;
+    ptr->intkey=intkey;
+    ptr->val=val;
+    ptr->lnext=dc_c_list;
+    dc_c_list=ptr;
+    dc_c_numelements++;
+  } else { // Insert in the beginning of linked list
+    dchashlistnode_t * node;
+    dchashlistnode_t *search=ptr;
+    
+    //make sure it isn't here
+    do {
+      if(search->key == key&&search->intkey==intkey) {
+       return;
+      }
+      search=search->next;
+    } while(search != NULL);
+
+    dc_c_numelements++;
+    if (dc_c_structs->num<NUMCLIST) {
+      node=&dc_c_structs->array[dc_c_structs->num];
+      dc_c_structs->num++;
+    } else {
+      //get new list
+      dcliststruct_t *tcl=calloc(1,sizeof(dcliststruct_t));
+      tcl->next=dc_c_structs;
+      dc_c_structs=tcl;
+      node=&tcl->array[0];
+      tcl->num=1;
+    }
+    node->key = key;
+    node->intkey = intkey;
+    node->val = val;
+    node->next = ptr->next;
+    ptr->next=node;
+    node->lnext=dc_c_list;
+    dc_c_list=node;
+  }
+}
+#endif
+
+#ifdef STMARRAY
+//Store objects and their pointers into hash
+void dc_t_chashInsertOnce(void * key, unsigned int indexkey, void *val) {
   chashlistnode_t *ptr;
 
   if (key==NULL)
@@ -119,9 +422,10 @@ void dc_t_chashInsertOnce(void * key, void *val) {
     dc_c_list=node;
   }
 }
+#endif
 
 unsigned int dc_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
+  dchashlistnode_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;
@@ -131,7 +435,7 @@ unsigned int dc_t_chashResize(unsigned int newsize) {
   oldsize = dc_c_size;
   dc_c_list=NULL;
 
-  if((node = calloc(newsize, sizeof(chashlistnode_t))) == NULL) {
+  if((node = calloc(newsize, sizeof(dchashlistnode_t))) == NULL) {
     printf("Calloc error %s %d\n", __FILE__, __LINE__);
     return 1;
   }
@@ -146,17 +450,28 @@ unsigned int dc_t_chashResize(unsigned int newsize) {
     isfirst = 1;
     do {                      //Inner loop to go through linked lists
       void * key;
-      chashlistnode_t *tmp,*next;
+#ifdef STMARRAY
+      unsigned int intkey;
+#endif
+      dchashlistnode_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
       }
+#ifdef STMARRAY
+      intkey=curr->intkey;
+      index = (((unsigned INTPTR)key^intkey) & mask) >>4;
+#else
       index = (((unsigned INTPTR)key) & mask) >>4;
+#endif
       tmp=&node[index];
       next = curr->next;
       // Insert into the new table
       if(tmp->key == 0) {
        tmp->key = key;
+#ifdef STMARRAY
+       tmp->intkey = intkey;
+#endif
        tmp->val = curr->val;
        tmp->lnext=dc_c_list;
        dc_c_list=tmp;
@@ -189,9 +504,9 @@ unsigned int dc_t_chashResize(unsigned int newsize) {
 //Delete the entire hash table
 void dc_t_chashDelete() {
   int i;
-  cliststruct_t *ptr=dc_c_structs;
+  dcliststruct_t *ptr=dc_c_structs;
   while(ptr!=NULL) {
-    cliststruct_t *next=ptr->next;
+    dcliststruct_t *next=ptr->next;
     free(ptr);
     ptr=next;
   }
@@ -200,6 +515,39 @@ void dc_t_chashDelete() {
   dc_c_structs=NULL;
   dc_c_list=NULL;
 }
+
+// Search for an address for a given oid
+INLINE void * dc_t_chashSearch(void * key) {
+  //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
+  dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
+  
+  do {
+    if(node->key == key) {
+      return node->val;
+    }
+    node = node->next;
+  } while(node != NULL);
+
+  return NULL;
+}
+
+#ifdef STMARRAY
+// Search for an address for a given oid
+INLINE void * dc_t_chashSearchArray(void * key, unsigned int intkey) {
+  //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE
+  dchashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key^intkey) & dc_c_mask)>>4];
+  
+  do {
+    if(node->key == key && node->intkey==intkey) {
+      return node->val;
+    }
+    node = node->next;
+  } while(node != NULL);
+
+  return NULL;
+}
+#endif
+
 #endif
 
 void t_chashCreate(unsigned int size, double loadfactor) {
@@ -231,7 +579,7 @@ void t_chashreset() {
       chashlistnode_t *next=tmpptr->lnext;
       if (tmpptr>=ptr&&tmpptr<top) {
        //zero in list
-       tmpptr->key=0;
+       tmpptr->key=NULL;
        tmpptr->next=NULL;
       }
       tmpptr=next;