runtime support for read only TRANSREADS
authorbdemsky <bdemsky>
Mon, 13 Jul 2009 00:37:07 +0000 (00:37 +0000)
committerbdemsky <bdemsky>
Mon, 13 Jul 2009 00:37:07 +0000 (00:37 +0000)
Robust/src/Main/Main.java
Robust/src/Runtime/DSTM/interface/queue.c
Robust/src/Runtime/STM/stm.c
Robust/src/Runtime/STM/stmlock.c
Robust/src/Runtime/STM/stmlock.h
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/thread.c

index 270d4f906e99d632e27fe41183b1c1f7bea25b2e..5f18a514308643381f87bd0f589f0a31bb445271 100644 (file)
@@ -157,6 +157,8 @@ public class Main {
        state.DSM=true;
       else if (option.equals("-singleTM"))
        state.SINGLETM=true;
+      else if (option.equals("-readset"))
+       state.READSET=true;
       else if (option.equals("-webinterface"))
        state.WEBINTERFACE=true;
       else if (option.equals("-instructionfailures"))
index c892a030266b67d02f095c6995e1139c7c7e2739..fcb58191864383ea2b65ceacde1c56ab08ae47f8 100644 (file)
@@ -58,10 +58,10 @@ void movehead(int size) {
 void * gettail() {
   while(tailoffset==headoffset) {
     //Sleep
-    pthread_mutex_lock(&qlock);
-    if (tailoffset==headoffset)
-      pthread_cond_wait(&qcond, &qlock);
-    pthread_mutex_unlock(&qlock);
+    //    pthread_mutex_lock(&qlock);
+    //    if (tailoffset==headoffset)
+    //      pthread_cond_wait(&qcond, &qlock);
+    //    pthread_mutex_unlock(&qlock);
   }
   if (*((int *)(memory+tailoffset))==-1) {
     tailoffset=0; //do loop
index 57610e216f7189a61097fb2b8b774f477b2d835e..ac9867585413d63b22deb12d7dca7f768963f516 100644 (file)
@@ -249,6 +249,7 @@ void *objstrAlloc(unsigned int size) {
   }
 }
 
+
 /* =============================================================
  * transRead
  * -finds the objects either in main heap
@@ -345,6 +346,9 @@ int transCommit() {
 #endif
       objstrReset();
       t_chashreset();
+#ifdef READSET
+      rd_t_chashreset();
+#endif
 #ifdef DELAYCOMP
       dc_t_chashreset();
       ptrstack.count=0;
@@ -366,6 +370,9 @@ int transCommit() {
 #endif
       objstrReset();
       t_chashreset();
+#ifdef READSET
+      rd_t_chashreset();
+#endif
 #ifdef DELAYCOMP
       dc_t_chashreset();
       ptrstack.count=0;
@@ -374,6 +381,7 @@ int transCommit() {
 #endif
       return 0;
     }
+
     /* wait a random amount of time before retrying to commit transaction*/
     if(finalResponse == TRANS_SOFT_ABORT) {
 #ifdef TRANSSTATS
@@ -392,6 +400,9 @@ int transCommit() {
 #endif
        objstrReset();
        t_chashreset();
+#ifdef READSET
+       rd_t_chashreset();
+#endif
 #ifdef DELAYCOMP
        dc_t_chashreset();
        ptrstack.count=0;
@@ -423,6 +434,38 @@ int transCommit() {
     free(oidwrlocked); \
   }
 #endif
+
+#ifdef DELAYCOMP
+#define allocarrays int t_numelements=c_numelements+dc_c_numelements; \
+  if (t_numelements<200) { \
+    oidwrlocked=wrlocked; \
+  } else { \
+    oidwrlocked=malloc(t_numelements*sizeof(void *)); \
+  } \
+  if (c_numelements<200) { \
+    oidrdlocked=rdlocked; \
+    oidrdversion=rdversion; \
+  } else { \
+    int size=c_numelements*sizeof(void*); \
+    oidrdlocked=malloc(size); \
+    oidrdversion=malloc(size); \
+  }
+#else
+#define allocarrays if (c_numelements<200) { \
+    oidrdlocked=rdlocked; \
+    oidrdversion=rdversion; \
+    oidwrlocked=wrlocked; \
+  } else { \
+    int size=c_numelements*sizeof(void*); \
+    oidrdlocked=malloc(size); \
+    oidrdversion=malloc(size); \
+    oidwrlocked=malloc(size); \
+  }
+#endif
+
+
+
+
 /* ==================================================
  * traverseCache
  * - goes through the transaction cache and
@@ -445,33 +488,8 @@ int traverseCache() {
   void ** oidrdlocked;
   void ** oidwrlocked;
   int * oidrdversion;
-#ifdef DELAYCOMP
-  int t_numelements=c_numelements+dc_c_numelements;
-  if (t_numelements<200) {
-    oidwrlocked=wrlocked;
-  } else {
-    oidwrlocked=malloc(t_numelements*sizeof(void *));
-  }
-  if (c_numelements<200) {
-    oidrdlocked=rdlocked;
-    oidrdversion=rdversion;
-  } else {
-    int size=c_numelements*sizeof(void*);
-    oidrdlocked=malloc(size);
-    oidrdversion=malloc(size);
-  }
-#else
-  if (c_numelements<200) {
-    oidrdlocked=rdlocked;
-    oidrdversion=rdversion;
-    oidwrlocked=wrlocked;
-  } else {
-    int size=c_numelements*sizeof(void*);
-    oidrdlocked=malloc(size);
-    oidrdversion=malloc(size);
-    oidwrlocked=malloc(size);
-  }
-#endif
+  allocarrays;
+
   chashlistnode_t *ptr = c_table;
   /* Represents number of bins in the chash table */
   unsigned int size = c_size;
@@ -507,12 +525,8 @@ int traverseCache() {
            return TRANS_SOFT_ABORT;
              else 
            return TRANS_ABORT;
-          
          }
        } else {
-#ifdef DELAYCOMP
-      //TODO: check to see if we already have lock
-#endif
          if(version == header->version) {
            /* versions match */
            softabort=1;
@@ -544,7 +558,7 @@ int traverseCache() {
   } //end of for
 
 #ifdef DELAYCOMP
-  //acquire other locks
+  //acquire access set locks
   unsigned int numoidwrtotal=numoidwrlocked;
 
   chashlistnode_t *dc_curr = dc_c_list;
@@ -659,9 +673,97 @@ int traverseCache() {
        return TRANS_SOFT_ABORT;
       else 
        return TRANS_ABORT;
-      
     }
   }
+
+#ifdef READSET
+  //need to validate auxilary readset
+  rdchashlistnode_t *rd_curr = rd_c_list;
+  /* Inner loop to traverse the linked list of the cache lookupTable */
+  while(likely(rd_curr != NULL)) {
+    //if the first bin in hash table is empty
+    unsigned int version=rd_curr->version;
+    objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t));
+    if(header->lock>0) { //object is not locked
+      if (version!=header->version) {
+       //have to abort
+#ifdef DELAYCOMP
+       transAbortProcess(oidwrlocked, numoidwrtotal);
+#else
+       transAbortProcess(oidwrlocked, numoidwrlocked);
+#endif
+#ifdef STMSTATS
+       ABORTCOUNT(header);
+       (typesCausingAbort[TYPE(header)])++;
+#endif
+#if defined(STMSTATS)||defined(SOFTABORT)
+       if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion))
+         softabort=0;
+#endif
+       DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version);
+       DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version);
+       freearrays;
+       if (softabort)
+         return TRANS_SOFT_ABORT;
+       else
+         return TRANS_ABORT;   
+      }
+    } else {
+      //maybe we already have lock
+      if (version==header->version) {
+       void * key=rd_curr->key;
+#ifdef DELAYCOMP
+       //check to see if it is in the delaycomp table
+       {
+         chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
+         do {
+           if(node->key == key)
+             goto nextloopread;
+           node = node->next;
+         } while(node != NULL);
+       }
+#endif
+       //check normal table
+       {
+         chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4];
+         do {
+           if(node->key == key) {
+             objheader_t * headeraddr=&((objheader_t *) node->val)[-1];          
+             if(STATUS(headeraddr) & DIRTY) {
+               goto nextloopread;
+             }
+           }
+           node = node->next;
+         } while(node != NULL);
+       }
+      }
+#ifdef DELAYCOMP
+      //have to abort to avoid deadlock
+      transAbortProcess(oidwrlocked, numoidwrtotal);
+#else
+      transAbortProcess(oidwrlocked, numoidwrlocked);
+#endif
+
+#ifdef STMSTATS
+      ABORTCOUNT(header);
+      (typesCausingAbort[TYPE(header)])++;
+#endif
+#if defined(STMSTATS)||defined(SOFTABORT)
+      if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion))
+       softabort=0;
+#endif
+      DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version);
+      DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version);
+      freearrays;
+      if (softabort)
+       return TRANS_SOFT_ABORT;
+      else
+       return TRANS_ABORT;
+    }
+  nextloopread:
+    rd_curr = rd_curr->lnext;
+  }
+#endif
   
   /* Decide the final response */
 #ifdef DELAYCOMP
@@ -697,33 +799,8 @@ int alttraverseCache() {
   void ** oidrdlocked;
   int * oidrdversion;
   void ** oidwrlocked;
-#ifdef DELAYCOMP
-  int t_numelements=c_numelements+dc_c_numelements;
-  if (t_numelements<200) {
-    oidwrlocked=wrlocked;
-  } else {
-    oidwrlocked=malloc(t_numelements*sizeof(void *));
-  }
-  if (c_numelements<200) {
-    oidrdlocked=rdlocked;
-    oidrdversion=rdversion;
-  } else {
-    int size=c_numelements*sizeof(void*);
-    oidrdlocked=malloc(size);
-    oidrdversion=malloc(size);
-  }
-#else
-  if (c_numelements<200) {
-    oidrdlocked=rdlocked;
-    oidrdversion=rdversion;
-    oidwrlocked=wrlocked;
-  } else {
-    int size=c_numelements*sizeof(void*);
-    oidrdlocked=malloc(size);
-    oidrdversion=malloc(size);
-    oidwrlocked=malloc(size);
-  }
-#endif
+  allocarrays;
+
   chashlistnode_t *curr = c_list;
   /* Inner loop to traverse the linked list of the cache lookupTable */
   while(likely(curr != NULL)) {
@@ -790,7 +867,7 @@ int alttraverseCache() {
     //if the first bin in hash table is empty
     objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1];
     objheader_t *header=(objheader_t *)(((char *)dc_curr->key)-sizeof(objheader_t));
-    if(write_trylock(&header->lock)) { //can aquire write lock    
+    if(write_trylock(&header->lock)) { //can aquire write lock
       oidwrlocked[numoidwrtotal++] = header;
     } else {
       //maybe we already have lock
@@ -799,7 +876,7 @@ int alttraverseCache() {
       
       do {
        if(node->key == key) {
-         objheader_t * headeraddr=&((objheader_t *) node->val)[-1];      
+         objheader_t * headeraddr=&((objheader_t *) node->val)[-1];
          if(STATUS(headeraddr) & DIRTY) {
            goto nextloop;
          }
@@ -853,7 +930,21 @@ int alttraverseCache() {
        return TRANS_ABORT;
       }
 #ifdef DELAYCOMP
-      //TODO: check to see if we already have lock
+    } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) {
+      //couldn't get lock because we already have it
+      //check if it is the right version number
+      if (version!=header->version) {
+       transAbortProcess(oidwrlocked, numoidwrtotal);
+#ifdef STMSTATS
+       ABORTCOUNT(header);
+       (typesCausingAbort[TYPE(header)])++;
+       getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion);
+#endif
+       DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version);
+       DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version);
+       freearrays;
+       return TRANS_ABORT;
+      }
 #endif
     } else { /* cannot aquire lock */
       if(version == header->version) {
@@ -882,6 +973,93 @@ int alttraverseCache() {
     }
   }
 
+#ifdef READSET
+  //need to validate auxilary readset
+  rdchashlistnode_t *rd_curr = rd_c_list;
+  /* Inner loop to traverse the linked list of the cache lookupTable */
+  while(likely(rd_curr != NULL)) {
+    //if the first bin in hash table is empty
+    int version=rd_curr->version;
+    objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t));
+    if(header->lock>0) { //object is not locked
+      if (version!=header->version) {
+       //have to abort
+#ifdef DELAYCOMP
+       transAbortProcess(oidwrlocked, numoidwrtotal);
+#else
+       transAbortProcess(oidwrlocked, numoidwrlocked);
+#endif
+#ifdef STMSTATS
+       ABORTCOUNT(header);
+       (typesCausingAbort[TYPE(header)])++;
+#endif
+#if defined(STMSTATS)||defined(SOFTABORT)
+       if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion))
+         softabort=0;
+#endif
+       DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version);
+       DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version);
+       freearrays;
+       if (softabort)
+         return TRANS_SOFT_ABORT;
+       else
+         return TRANS_ABORT;   
+      }
+    } else {
+      if (version==header->version) {
+       void * key=rd_curr->key;
+#ifdef DELAYCOMP
+       //check to see if it is in the delaycomp table
+       {
+         chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4];
+         do {
+           if(node->key == key)
+             goto nextloopread;
+           node = node->next;
+         } while(node != NULL);
+       }
+#endif
+       //check normal table
+       {
+         chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4];
+         do {
+           if(node->key == key) {
+             objheader_t * headeraddr=&((objheader_t *) node->val)[-1];          
+             if(STATUS(headeraddr) & DIRTY) {
+               goto nextloopread;
+             }
+           }
+           node = node->next;
+         } while(node != NULL);
+       }
+      }
+#ifdef DELAYCOMP
+       //have to abort to avoid deadlock
+       transAbortProcess(oidwrlocked, numoidwrtotal);
+#else
+       transAbortProcess(oidwrlocked, numoidwrlocked);
+#endif
+#ifdef STMSTATS
+      ABORTCOUNT(header);
+      (typesCausingAbort[TYPE(header)])++;
+#endif
+#if defined(STMSTATS)||defined(SOFTABORT)
+      if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion))
+       softabort=0;
+#endif
+      DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version);
+      DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version);
+      freearrays;
+      if (softabort)
+       return TRANS_SOFT_ABORT;
+      else
+       return TRANS_ABORT;
+    }
+  nextloopread:
+    rd_curr = rd_curr->lnext;
+  }
+#endif
+
   /* Decide the final response */
 #ifdef DELAYCOMP
   transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params);
index 15ef3ab94399c39c47b10e4784194d46a0814012..7da44b6673586ca3be54f06f8bad897dc1d80f84 100644 (file)
@@ -6,6 +6,7 @@ inline void initdsmlocks(volatile unsigned int *addr) {
   (*addr) = RW_LOCK_BIAS;
 }
 
+/*
 int write_trylock(volatile unsigned int *lock) {
   int retval=0;
   __asm__ __volatile__("xchgl %0,%1"
@@ -14,6 +15,7 @@ int write_trylock(volatile unsigned int *lock) {
               : "memory");
   return retval;
 }
+*/
 
 void write_unlock(volatile unsigned int *lock) {
   __asm __volatile__("movl $1, %0" : "+m" (*__xg(lock))::"memory");
index 4c79da49e514b6c5c1a6382e72d7b964f99033c5..7b9c6d76700e2b882d3fde214ca3420460395145 100644 (file)
@@ -11,14 +11,14 @@ struct __xchg_dummy {
 #define __xg(x) ((struct __xchg_dummy *)(x))
 
 void initdsmlocks(volatile unsigned int *addr);
-int write_trylock(volatile unsigned int *lock);
+//int write_trylock(volatile unsigned int *lock);
 void write_unlock(volatile unsigned int *lock);
 
 /*
 static inline void initdsmlocks(volatile unsigned int *addr) {
   (*addr) = RW_LOCK_BIAS;
 }
-
+*/
 static inline int write_trylock(volatile unsigned int *lock) {
   int retval=0;
   __asm__ __volatile__("xchgl %0,%1"
@@ -28,6 +28,7 @@ static inline int write_trylock(volatile unsigned int *lock) {
   return retval;
 }
 
+/*
 static inline void write_unlock(volatile unsigned int *lock) {
   __asm __volatile__("movl $1, %0" : "+m" (*__xg(lock))::"memory");
 }
index 7c7afe33c229ca231db05bd0a44c4203a3f31b67..12345be618cec1cf3cf323b6ceaad17620686914 100644 (file)
@@ -10,6 +10,197 @@ __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;
@@ -48,7 +239,7 @@ void dc_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;
@@ -247,7 +438,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;
index cecb80516f778d5371bf84f479c5ac6a68901416..378f1c98219320a3ab4951f44873d451c7786165 100644 (file)
@@ -17,7 +17,6 @@
 
 #define INLINE    inline __attribute__((always_inline))
 
-
 typedef struct chashlistnode {
   void * key;
   void * val;     //this can be cast to another type or used to point to a larger structure
@@ -49,7 +48,6 @@ unsigned int t_chashResize(unsigned int newsize);
 void t_chashDelete();
 void t_chashreset();
 
-
 extern __thread chashlistnode_t *c_table;
 extern __thread chashlistnode_t *c_list;
 extern __thread unsigned int c_size;
@@ -59,6 +57,38 @@ extern __thread unsigned int c_threshold;
 extern __thread double c_loadfactor;
 extern __thread cliststruct_t *c_structs;
 
+#ifdef READSET
+
+typedef struct rdchashlistnode {
+  void * key;
+  unsigned int version;
+  struct rdchashlistnode *next;
+  struct rdchashlistnode *lnext;
+} rdchashlistnode_t;
+
+typedef struct rdclist {
+  struct rdchashlistnode array[NUMCLIST];
+  int num;
+  struct rdclist *next;
+} rdcliststruct_t;
+
+
+extern __thread rdchashlistnode_t *rd_c_table;
+extern __thread rdchashlistnode_t *rd_c_list;
+extern __thread unsigned int rd_c_size;
+extern __thread unsigned INTPTR rd_c_mask;
+extern __thread unsigned int rd_c_numelements;
+extern __thread unsigned int rd_c_threshold;
+extern __thread double rd_c_loadfactor;
+extern __thread rdcliststruct_t *rd_c_structs;
+
+void rd_t_chashCreate(unsigned int size, double loadfactor);
+void rd_t_chashInsertOnce(void * key, unsigned int val);
+unsigned int rd_t_chashResize(unsigned int newsize);
+void rd_t_chashDelete();
+void rd_t_chashreset();
+#endif
+
 #ifdef DELAYCOMP
 extern __thread chashlistnode_t *dc_c_table;
 extern __thread chashlistnode_t *dc_c_list;
@@ -76,5 +106,4 @@ unsigned int dc_t_chashResize(unsigned int newsize);
 void dc_t_chashDelete();
 void dc_t_chashreset();
 #endif
-
 #endif
index 05937ffad83a9f307b7ebf563e9359d4de1fffea..318f6cfb24a3a473f27035162c023c47a2cf63b2 100644 (file)
@@ -8,7 +8,7 @@
 #define TRANS_SOFT_ABORT    12
 #define TRANS_ABORT         13
 #define TRANS_COMMIT        14
-
+#define TRANS_ABORT_RETRY         15
 
 /* ========================
  * Library header files
@@ -107,6 +107,19 @@ typedef struct objheader {
           } while(1); \
         }}
 
+#define TRANSREADRD(x,y) { \
+    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=inputvalue;rd_t_chashInsertOnce(inputvalue, ((objheader_t *)inputvalue)[-1].version); break;}} \
+          } while(1); \
+        }}
+
 /* =================================
  * Data structures
  * =================================
@@ -169,6 +182,9 @@ objheader_t *transCreateObj(void * ptr, unsigned int size);
 unsigned int getNewOID(void);
 void *objstrAlloc(unsigned int size);
 __attribute__((pure)) void *transRead(void *, void *);
+#ifdef READSET
+__attribute__((pure)) void *transReadOnly(void *);
+#endif
 #ifdef DELAYCOMP
 int transCommit(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params);
 int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params);
index 1ef15582de2d50262d168fae510c5257221b4e91..5736285fc1c3fdbf84b9011a0586b72be910ae34 100644 (file)
 
 #define NUMPTRS 100
 
-#define INITIALHEAPSIZE 256*1024*1024
-#define GCPOINT(x) ((int)((x)*0.99))
+#define INITIALHEAPSIZE 1024*1024*1024L
+#define GCPOINT(x) ((INTPTR)((x)*0.99))
 /* This define takes in how full the heap is initially and returns a new heap size to use */
-#define HEAPSIZE(x,y) ((int)(x+y))*2
+#define HEAPSIZE(x,y) ((INTPTR)(x+y))*2
 
 #ifdef TASK
 extern struct genhashtable * activetasks;
@@ -742,9 +742,9 @@ void * mygcmalloc(struct garbagelist * stackptr, int size) {
 
     /* Grow the to heap if necessary */
     {
-      int curr_heapsize=curr_heaptop-curr_heapbase;
-      int to_heapsize=to_heaptop-to_heapbase;
-      int last_heapsize=0;
+      INTPTR curr_heapsize=curr_heaptop-curr_heapbase;
+      INTPTR to_heapsize=to_heaptop-to_heapbase;
+      INTPTR last_heapsize=0;
       if (lastgcsize>0) {
        last_heapsize=HEAPSIZE(lastgcsize, size);
        if ((last_heapsize&7)!=0)
index 0180ef5787c8b147072042851c99b2e708e89921..66b9d354f20cdc583b1f0a98fe70939a63bf1fee 100644 (file)
@@ -180,6 +180,9 @@ void initializethreads() {
   t_cache = objstrCreate(1048576);
   t_reserve=NULL;
   t_chashCreate(CHASH_SIZE, CLOADFACTOR);
+#ifdef READSET
+  rd_t_chashCreate(CHASH_SIZE, CLOADFACTOR);
+#endif
 #ifdef DELAYCOMP
   dc_t_chashCreate(CHASH_SIZE, CLOADFACTOR);
   ptrstack.count=0;
@@ -247,6 +250,9 @@ void initthread(struct ___Thread___ * ___this___) {
   t_cache = objstrCreate(1048576);
   t_reserve=NULL;
   t_chashCreate(CHASH_SIZE, CLOADFACTOR);
+#ifdef READSET
+  rd_t_chashCreate(CHASH_SIZE, CLOADFACTOR);
+#endif
 #ifdef DELAYCOMP
   dc_t_chashCreate(CHASH_SIZE, CLOADFACTOR);
   ptrstack.count=0;