Changes to prefetch object stores
authorbdemsky <bdemsky>
Fri, 20 Feb 2009 04:49:31 +0000 (04:49 +0000)
committerbdemsky <bdemsky>
Fri, 20 Feb 2009 04:49:31 +0000 (04:49 +0000)
Robust/src/Runtime/DSTM/interface/dstm.h
Robust/src/Runtime/DSTM/interface/gCollect.c
Robust/src/Runtime/DSTM/interface/gCollect.h
Robust/src/Runtime/DSTM/interface/prelookup.c
Robust/src/Runtime/DSTM/interface/trans.c

index 8a458dc585bce931cc289d8a0140438250f33072..9a65fdb4543a998ca86834dbf2a8003444720455 100644 (file)
@@ -155,6 +155,7 @@ typedef struct objstr {
   unsigned int size;       //this many bytes are allocated after this header
   void *top;
   struct objstr *next;
+  struct objstr *prev;
 } objstr_t;
 
 typedef struct oidmidpair {
index 98b1fa80151ecbcd09f067456c163c4d6071dc43..1707b230202ee4bb8c5f9838ef432d78e9bb6234 100644 (file)
 #include "gCollect.h"
 #include "prelookup.h"
 
-extern objstr_t *prefetchcache; //Global Prefetch cache
+
 extern pthread_mutex_t prefetchcache_mutex; //Mutex to lock Prefetch Cache
 extern prehashtable_t pflookup; //Global prefetch cache  lookup table
-prefetchNodeInfo_t *pNodeInfo; //Global prefetch holding metadata
+prefetchNodeInfo_t pNodeInfo; //Global prefetch holding metadata
+
+#define OSUSED(x) (((unsigned int)(x)->top)-((unsigned int) (x+1)))
+#define OSFREE(x) ((x)->size-OSUSED(x))
 
 void initializePCache() {
-  pNodeInfo = calloc(1, sizeof(prefetchNodeInfo_t)); //Not freed yet
-  pNodeInfo->oldptr = prefetchcache;
-  pNodeInfo->newptr = NULL;
-  pNodeInfo->num_old_objstr = 1; //for prefetch cache allocated by objstralloc in trans.c file
-  pNodeInfo->maxsize = DEFAULT_OBJ_STORE_SIZE;
+  objstr_t * os=objstrCreate(DEFAULT_OBJ_STORE_SIZE);
+  pNodeInfo.oldptr = os;
+  pNodeInfo.newptr = os;
+  pNodeInfo.os_count = 1; //for prefetch cache allocated by objstralloc in trans.c file
+  pNodeInfo.oldstale=NULL;
+  pNodeInfo.newstale=NULL;
+  pNodeInfo.stale_count=0;
+  pNodeInfo.stall=0;
 }
 
-void *prefetchobjstrAlloc(unsigned int size) {
-  void * ptr = NULL;
-  if(pNodeInfo->num_old_objstr <= PREFETCH_FLUSH_COUNT_THRESHOLD) {
-    //regular allocation
-    if((ptr = normalPrefetchAlloc(prefetchcache, size)) == NULL) {
-      printf("Error: %s() prefetch cache alloc error %s, %d\n", __func__, __FILE__, __LINE__);
-      return NULL;
-    }
-    return ptr;
+objstr_t * getObjStr(unsigned int size) {
+  if (pNodeInfo.stall>0)
+    pNodeInfo.stall--;
+  if (size<=DEFAULT_OBJ_STORE_SIZE&&pNodeInfo.stale_count>STALE_MINTHRESHOLD&&pNodeInfo.stall==0) {
+    //recycle
+    objstr_t * tmp=pNodeInfo.oldstale;
+    pNodeInfo.oldstale=pNodeInfo.oldstale->prev;
+    if (pNodeInfo.oldstale==NULL)
+      pNodeInfo.newstale=NULL;
+    pNodeInfo.stale_count--;
+    tmp->top=tmp+1;
+    tmp->prev=NULL;
+    return tmp;
   } else {
-    // Iterate through available blocks to see if size can be allocated
-    if((ptr = lookUpFreeSpace(pNodeInfo->newptr, pNodeInfo->oldptr, size)) != NULL) {
-      return ptr;
-    } else { //allocate new block if size not available
-      if(size >= pNodeInfo->maxsize) {
-       if((ptr = allocateNew(size)) == NULL) {
-         printf("Error: %s() Calloc error %s %d\n", __func__, __FILE__, __LINE__);
-         return NULL;
-       }
-       return ptr;
-      } else { //If size less then reclaim old blocks
-       clearNBlocks(pNodeInfo->oldptr, pNodeInfo->newptr);
-       //update oldptr and newptr
-       updatePtrs();
-       //look for free space if available in the free blocks
-       if((ptr = lookUpFreeSpace(pNodeInfo->newptr, pNodeInfo->oldptr, size)) != NULL) {
-         return ptr;
-       } else {
-         if((ptr = allocateNew(size)) == NULL) {
-           printf("Error: %s() Calloc error %s %d\n", __func__, __FILE__, __LINE__);
-           return NULL;
-         }
-         return ptr;
-       }
-      }
-    }
+    int allocsize=(size>DEFAULT_OBJ_STORE_SIZE)?size:DEFAULT_OBJ_STORE_SIZE;
+    return objstrCreate(allocsize);
   }
 }
 
-void *normalPrefetchAlloc(objstr_t *store, unsigned int size) {
-  void *tmp;
-  while (1) {
-    if(((unsigned int)store->top - (((unsigned int)store) + sizeof(objstr_t)) + size) <= store->size) { //store not full
-      tmp = store->top;
-      store->top += size;
-      return tmp;
-    }
-    //store full
-    if(store->next == NULL) {
-      //end of list, all full
-      if(size > DEFAULT_OBJ_STORE_SIZE) {
-       //in case of large objects
-       if((store->next = (objstr_t *) calloc(1,(sizeof(objstr_t) + size))) == NULL) {
-         printf("%s() Calloc error at line %d, %s\n", __func__, __LINE__, __FILE__);
-         return NULL;
-       }
-       store = store->next;
-       store->size = size;
+void *prefetchobjstrAlloc(unsigned int size) {
+  //try existing space in first two OS
+  objstr_t *os=pNodeInfo.newptr;
+  if (size<=OSFREE(os)) {
+    void *tmp=os->top;
+    os->top=((char *)os->top)+size;
+    return tmp;
+  }
+  if ((os=os->next)!=NULL&&(size<=OSFREE(os))) {
+    void *tmp=os->top;
+    os->top=((char *)os->top)+size;
+    return tmp;
+  }
+  //need to allocate new space
+  objstr_t *tmp=getObjStr(size);;
+
+  //link new node in
+  tmp->next=pNodeInfo.newptr;
+  pNodeInfo.newptr->prev=tmp;
+  pNodeInfo.newptr=tmp;
+  pNodeInfo.os_count++;
+  
+  if (pNodeInfo.os_count>PREFETCH_FLUSH_THRESHOLD) {
+    //remove oldest from linked list
+    objstr_t *tofree=pNodeInfo.oldptr;
+    pNodeInfo.oldptr=tofree->prev;
+    pNodeInfo.os_count--;
+    //need to flush cache
+    clearBlock(tofree);
+    if (pNodeInfo.stale_count>STALE_MAXTHRESHOLD) {
+      //need to toss store
+      free(tofree);
+    } else {
+      if (pNodeInfo.newstale==NULL) {
+       //first store
+       pNodeInfo.newstale=pNodeInfo.oldstale=tofree;
+       tofree->prev=NULL;
+       pNodeInfo.stale_count++;
       } else {
-       if((store->next = (objstr_t *) calloc(1, (sizeof(objstr_t) + DEFAULT_OBJ_STORE_SIZE))) == NULL) {
-         printf("%s() Calloc error at line %d, %s\n", __func__, __LINE__, __FILE__);
-         return NULL;
-       }
-       store = store->next;
-       store->size = DEFAULT_OBJ_STORE_SIZE;
+       //just add it to the list
+       pNodeInfo.newstale->prev=tofree;
+       pNodeInfo.newstale=tofree;
+       pNodeInfo.stale_count++;
       }
-      //Update maxsize of objstr blocks, num of blocks and newptr
-      pNodeInfo->num_old_objstr++;
-      if(pNodeInfo->num_old_objstr <= PREFETCH_FLUSH_COUNT_THRESHOLD/2)
-       pNodeInfo->newptr = store;
-      if(pNodeInfo->maxsize < size)
-       pNodeInfo->maxsize = size;
-      store->top = (void *)(((unsigned int)store) + sizeof(objstr_t) + size);
-      return (void *)(((unsigned int)store) + sizeof(objstr_t));
-    } else {
-      store = store->next;
     }
   }
-}
 
-void *lookUpFreeSpace(void *startAddr, void *endAddr, int size) {
-  objstr_t *ptr;
-  void *tmp;
-  ptr = (objstr_t *)(startAddr);
-  while(ptr != NULL && ((unsigned long int)ptr!= (unsigned long int)endAddr)) {
-    if(((unsigned int)ptr->top - (((unsigned int)ptr) + sizeof(objstr_t)) + size) <= ptr->size) { //store not full
-      tmp = ptr->top;
-      ptr->top += size;
-      return tmp;
-    }
-    ptr = ptr->next;
-  }
-  return NULL;
+  void *ptr=tmp->top;
+  tmp->top=((char *)tmp->top)+size;
+  return ptr;
 }
 
-void clearNBlocks(void *oldaddr, void * newaddr) {
-  int count = 0;
-  objstr_t *tmp = (objstr_t *) oldaddr;
+void clearBlock(objstr_t *block) {
+  unsigned long int tmpbegin=(unsigned int)block;
+  unsigned long int tmpend=(unsigned int)block->top;
+  int i, j;
+  prehashlistnode_t *ptr;
   pthread_mutex_lock(&pflookup.lock);
-  while(((unsigned int) tmp != (unsigned int)newaddr) && (tmp != NULL)) {
-    void * begin = (void *)tmp+sizeof(objstr_t);
-    void * end = (void *)tmp+sizeof(objstr_t)+tmp->size;
-    tmp->top = (void *)tmp+sizeof(objstr_t);
-    clearPLookUpTable(begin, end);
-    //TODO only for testing purpose, remove later
-    memset(tmp->top, 0, tmp->size);
-    tmp = tmp->next;
-  }
-  pthread_mutex_unlock(&pflookup.lock);
-}
 
-void clearPLookUpTable(void *begin, void *end) {
-  unsigned long int tmpbegin;
-  unsigned long int tmpend;
-  tmpbegin = (unsigned long int) begin;
-  tmpend = (unsigned long int) end;
-  int i, j;
-  prehashlistnode_t *ptr = pflookup.table;
+  ptr = pflookup.table;
   for(i = 0; i<pflookup.size; i++) {
-    prehashlistnode_t *curr = &ptr[i];
-    for(; curr != NULL; curr = curr->next) {
-      if(((unsigned long int)(curr->val) >= tmpbegin) && ((unsigned long int)(curr->val) < tmpend)) {
-       unsigned int oid = curr->key;
-       objheader_t *objheader;
-       if((objheader = prehashSearch(oid)) != NULL) {
-         prehashRemove(oid);
+    prehashlistnode_t *orig=&ptr[i];
+    prehashlistnode_t *curr = orig;
+    prehashlistnode_t *next=curr->next;
+    for(; next != NULL; curr=next, next = next->next) {
+      unsigned int val=(unsigned int)next->val;
+      if ((val>=tmpbegin)&(val<tmpend)) {
+       curr->next=next->next;
+       free(next);
+      }
+    }
+    {
+      unsigned int val=(unsigned int)orig->val;
+      if ((val>=tmpbegin)&(val<tmpend)) {
+       if (orig->next==NULL) {
+         orig->key=0;
+         orig->val=NULL;
+       } else {
+         next=orig->next;
+         orig->val=next->val;
+         orig->key=next->key;
+         orig->next=next->next;
+         free(next);
        }
       }
     }
   }
+  pthread_mutex_unlock(&pflookup.lock);
 }
 
-void updatePtrs() {
-  void *ptr;
-  ptr = pNodeInfo->oldptr;
-  pNodeInfo->oldptr = pNodeInfo->newptr;
-  pNodeInfo->newptr = ptr;
-}
-
-void *allocateNew(unsigned int size) {
+objstr_t *allocateNew(unsigned int size) {
   objstr_t *tmp;
   if((tmp = (objstr_t *) calloc(1, (sizeof(objstr_t) +size))) == NULL) {
     printf("Error: %s() Calloc error %s %d\n", __func__, __FILE__, __LINE__);
@@ -162,11 +138,6 @@ void *allocateNew(unsigned int size) {
   tmp->size = size;
   tmp->top = (void *)(((unsigned int)tmp) + sizeof(objstr_t) + size);
   //Insert newly allocated block into linked list of prefetch cache
-  tmp->next = ((objstr_t *)(pNodeInfo->newptr))->next;
-  ((objstr_t *)(pNodeInfo->newptr))->next = tmp;
-  pNodeInfo->num_old_objstr++;
   // Update maxsize of prefetch objstr blocks
-  if(pNodeInfo->maxsize < tmp->size)
-    pNodeInfo->maxsize = tmp->size;
-  return (void *)(((unsigned int)tmp) + sizeof(objstr_t));
+  return tmp;
 }
index 3bf6a71c7982630098c8e2d0bb525da6b1f19d65..5a1b8e4ace1f3c2557b371abe2c27e06cf1bfcba 100644 (file)
@@ -6,27 +6,38 @@
 /***********************************
  ****** Global constants **********
  **********************************/
-#define PREFETCH_FLUSH_COUNT_THRESHOLD 30
+
+#define STALE_MINTHRESHOLD 30
+
+#define STALE_MAXTHRESHOLD 40 //ugly hack..if you make this too small things
+// will fail in odd subtle ways
+
+#define PREFETCH_FLUSH_THRESHOLD 20
+#define STALL_THRESHOLD 30
+
+
 
 /*********************************
  ********* Global variables ******
  ********************************/
 typedef struct prefetchNodeInfo {
-  void *oldptr;
-  void *newptr;
-  int num_old_objstr;
-  int maxsize;
+  objstr_t *oldptr;
+  objstr_t *newptr;
+  int os_count;
+
+  objstr_t *oldstale;
+  objstr_t *newstale;
+  int stale_count;
+  int stall;
+  
 } prefetchNodeInfo_t;
 
 /********************************
  ******** Functions ************
  *******************************/
 void *prefetchobjstrAlloc(unsigned int size);
-void *normalPrefetchAlloc(objstr_t *, unsigned int);
 void initializePCache();
-void *lookUpFreeSpace(void *, void *, int);
-void clearNBlocks(void *, void *);
-void clearPLookUpTable(void *, void *);
-void updatePtrs();
-void *allocateNew(unsigned int size);
+void clearBlock(objstr_t *);
+objstr_t *allocateNew(unsigned int size);
+objstr_t * getObjStr(unsigned int size);
 #endif
index 79a616f4ea96dbbf6f97cf09f254fe9cf1c83beb..0e3c17c9c6c13b1bb1e6ada8f55afea018ea6347 100644 (file)
@@ -1,6 +1,9 @@
 /* LOCK THE ENTIRE HASH TABLE */
 #include "prelookup.h"
+#include "gCollect.h"
 extern objstr_t *prefetchcache;
+extern pthread_mutex_t prefetchcache_mutex; //Mutex to lock Prefetch Cache
+extern prefetchNodeInfo_t pNodeInfo;
 
 prehashtable_t pflookup; //Global prefetch cache table
 
@@ -13,8 +16,6 @@ unsigned int prehashCreate(unsigned int size, float loadfactor) {
     printf("Calloc error %s %d\n", __FILE__, __LINE__);
     return 1;
   }
-  pflookup.hack=NULL;
-  pflookup.hack2=NULL;
   pflookup.table = nodes;
   pflookup.size = size;
   pflookup.numelements = 0; // Initial number of elements in the hash
@@ -195,9 +196,6 @@ void prehashClear() {
   int i, isFirstBin;
   prehashlistnode_t *ptr, *prev, *curr;
 
-  objstr_t *oldcache=prefetchcache;
-  prefetchcache=objstrCreate(prefetchcache->size);
-
   pthread_mutex_lock(&pflookup.lock);
   ptr = pflookup.table;
   for(i = 0; i < pflookup.size; i++) {
@@ -214,13 +212,30 @@ void prehashClear() {
       prev->next = NULL;
     }
   }
-  pthread_mutex_unlock(&pflookup.lock);
-
-  if (pflookup.hack2!=NULL) {
-    objstrDelete(pflookup.hack2);
+  {
+    int stale;
+    pthread_mutex_unlock(&pflookup.lock);
+    pthread_mutex_lock(&prefetchcache_mutex);
+    if (pNodeInfo.newstale==NULL) {
+      //transfer the list wholesale;
+      pNodeInfo.oldstale=pNodeInfo.oldptr;
+      pNodeInfo.newstale=pNodeInfo.newptr;
+    } else {
+      //merge the two lists
+      pNodeInfo.newstale->prev=pNodeInfo.oldptr;
+      pNodeInfo.newstale=pNodeInfo.newptr;
+    }
+    stale=STALL_THRESHOLD-pNodeInfo.stale_count;
+    
+    if (stale>0&&stale>pNodeInfo.stall)
+      pNodeInfo.stall=stale;
+
+    pNodeInfo.stale_count+=pNodeInfo.os_count;
+    pNodeInfo.oldptr=getObjStr(DEFAULT_OBJ_STORE_SIZE);
+    pNodeInfo.newptr=pNodeInfo.oldptr;
+    pNodeInfo.os_count=1;
+    pthread_mutex_unlock(&prefetchcache_mutex);
   }
-  pflookup.hack2=pflookup.hack;
-  pflookup.hack=oldcache;
 #endif
 }
 
index 528dafabcba53a2f0258fa501e94112a9b05edd5..7c1b2fc53b3302358a85e95bb8be78418f804226 100644 (file)
@@ -20,7 +20,6 @@
 #endif
 
 #define NUM_THREADS 1
-#define PREFETCH_CACHE_SIZE 1048576 //1MB
 #define CONFIG_FILENAME "dstm.conf"
 
 
@@ -29,7 +28,6 @@ extern int classsize[];
 pfcstats_t *evalPrefetch;
 extern int numprefetchsites; //Global variable containing number of prefetch sites
 extern pthread_mutex_t mainobjstore_mutex; // Mutex to lock main Object store
-objstr_t *prefetchcache; //Global Prefetch cache
 pthread_mutex_t prefetchcache_mutex; // Mutex to lock Prefetch Cache
 pthread_mutexattr_t prefetchcache_mutex_attr; /* Attribute for lock to make it a recursive lock */
 extern prehashtable_t pflookup; //Global Prefetch cache's lookup table
@@ -258,7 +256,6 @@ void *pCacheAlloc(objstr_t *store, unsigned int size) {
 void transInit() {
   //Create and initialize prefetch cache structure
 #ifdef CACHE
-  prefetchcache = objstrCreate(PREFETCH_CACHE_SIZE);
   initializePCache();
   if((evalPrefetch = initPrefetchStats()) == NULL) {
     printf("%s() Error allocating memory at %s, %d\n", __func__, __FILE__, __LINE__);