fix for migration
[charm.git] / src / conv-core / isomalloc.c
index 11ffbc0b4da11bef227ff58be890e0b1040cc594..e784d44271d99d39c60676cc0a6aad446853911e 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$ 
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 /**************************************************************************
 Isomalloc:
 A way to allocate memory at the same address on every processor.
@@ -44,7 +37,7 @@ added by Ryan Mokos in July 2008.
 #include "converse.h"
 #include "memory-isomalloc.h"
 
-#define CMK_THREADS_DEBUG 0
+#define ISOMALLOC_DEBUG 0
 
 /* 0: use the old isomalloc implementation (array)
 1: use the new isomalloc implementation (b-tree)  */
@@ -67,11 +60,15 @@ added by Ryan Mokos in July 2008.
 #include <sys/personality.h>
 #endif
 
-#if USE_MEMPOOL_ISOMALLOC
+#if CMK_USE_MEMPOOL_ISOMALLOC
 #include "mempool.h"
+extern int cutOffPoints[cutOffNum];
 #endif 
 
 static int _sync_iso = 0;
+#if __FAULT__
+static int _restart = 0;
+#endif
 static int _mmap_probe = 0;
 
 static int read_randomflag(void)
@@ -138,9 +135,9 @@ static CmiInt8 pe2slot(int pe) {
   return pe*numslots;
 }
 /* Return the number of slots in a block with n user data bytes */
-#if USE_MEMPOOL_ISOMALLOC
+#if CMK_USE_MEMPOOL_ISOMALLOC
 static int length2slots(int nBytes) {
-  return (sizeof(CmiIsomallocBlock)+sizeof(mempool_type)+ sizeof(mempool_header)+nBytes+slotsize-1)/slotsize;
+  return (nBytes+slotsize-1)/slotsize;
 }
 #else
 static int length2slots(int nBytes) {
@@ -1261,7 +1258,7 @@ static void print_list_array(slotset *ss) {
   }
 }
 
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
 static void print_slots(slotset *ss) {
   print_btree_top_down(ss->btree_root);
   print_list_array(ss);
@@ -1447,7 +1444,7 @@ free_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
  }
  */
 
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
   static void
 print_slots(slotset *ss)
 {
@@ -1597,7 +1594,7 @@ map_slots(CmiInt8 slot, CmiInt8 nslots)
 
   if (pa==NULL)
   { /*Map just failed completely*/
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
     perror("mmap failed");
     CmiPrintf("[%d] tried to mmap %p, but encountered error\n",CmiMyPe(),addr);
 #endif
@@ -1605,13 +1602,13 @@ map_slots(CmiInt8 slot, CmiInt8 nslots)
   }
   if (pa != addr)
   { /*Map worked, but gave us back the wrong place*/
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
     CmiPrintf("[%d] tried to mmap %p, but got %p back\n",CmiMyPe(),addr,pa);
 #endif
     call_munmap(addr,slotsize*nslots);
     return NULL;
   }
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
   CmiPrintf("[%d] mmap'd slots %ld-%ld to address %p\n",CmiMyPe(),
       slot,slot+nslots-1,addr);
 #endif
@@ -1626,7 +1623,7 @@ unmap_slots(CmiInt8 slot, CmiInt8 nslots)
 {
   void *addr=slot2addr(slot);
   call_munmap(addr, slotsize*nslots);
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
   CmiPrintf("[%d] munmap'd slots %ld-%ld from address %p\n",CmiMyPe(),
       slot,slot+nslots-1,addr);
 #endif
@@ -1646,11 +1643,11 @@ static void map_failed(CmiInt8 s,CmiInt8 n)
 
 CpvStaticDeclare(slotset *, myss); /*My managed slots*/
 
-#if USE_MEMPOOL_ISOMALLOC
-CtvStaticDeclare(mempool_type *, threadpool); /*Thread managed pools*/
+#if CMK_USE_MEMPOOL_ISOMALLOC
+CtvDeclare(mempool_type *, threadpool); /*Thread managed pools*/
 
 //alloc function to be used by mempool
-void * isomallocfn (size_t *size, gni_mem_handle_t *mem_hndl)
+void * isomallocfn (size_t *size, mem_handle_t *mem_hndl, int expand_flag)
 {
   CmiInt8 s,n,i;
   void *newaddr;
@@ -1659,7 +1656,7 @@ void * isomallocfn (size_t *size, gni_mem_handle_t *mem_hndl)
   s=get_slots(CpvAccess(myss),n);
   if (s==-1) {
     CmiError("Not enough address space left on processor %d to isomalloc %d bytes!\n",
-              CmiMyPe(),*size);
+        CmiMyPe(),*size);
     CmiAbort("Out of virtual address space for isomalloc");
   }
   grab_slots(CpvAccess(myss),s,n);
@@ -1672,17 +1669,15 @@ void * isomallocfn (size_t *size, gni_mem_handle_t *mem_hndl)
 #endif
   }
   if (!newaddr) map_failed(s,n);
-  *mem_hndl = s;
+  *((CmiInt8 *)mem_hndl) = s;
   *size = n*slotsize;
-  printf("Alloc slot long %lld from %p to %p\n",s,newaddr,newaddr+*size);
   return newaddr;
 }
 
 //free function to be used by mempool
-void isofreefn(void *ptr, gni_mem_handle_t mem_hndl)
+void isofreefn(void *ptr, mem_handle_t mem_hndl)
 {
-  printf("Free slots at %p for slot %lld\n", ptr, mem_hndl); 
-  call_munmap(ptr, ((mempool_block *)ptr)->size);
+  call_munmap(ptr, ((block_header *)ptr)->size);
 }
 #endif
 
@@ -1730,7 +1725,7 @@ static int bad_location(char *loc) {
   void *addr;
   addr=call_mmap_fixed(loc,slotsize);
   if (addr==NULL || addr!=loc) {
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
     CmiPrintf("[%d] Skipping unmappable space at %p\n",CmiMyPe(),loc);
 #endif
     return 1; /*No good*/
@@ -1759,7 +1754,7 @@ static int partially_good(char *start,memRange_t len,int n) {
 static int good_range(char *start,memRange_t len,int n) {
   int i;
   memRange_t quant=divide_range(len,n);
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
   CmiPrintf("good_range: %lld, %d\n", quant, n);
 #endif
   CmiAssert (quant > 0);
@@ -1800,7 +1795,7 @@ static void check_range(char *start,char *end,memRegion_t *max)
   }
 #endif
   if (len<=max->len) return; /*It's too short already!*/
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
   CmiPrintf("[%d] Checking at %p - %p\n",CmiMyPe(),start,end);
 #endif
 
@@ -1808,7 +1803,7 @@ static void check_range(char *start,char *end,memRegion_t *max)
   if (!good_range(start,len,256)) {
     /* Try to split into subranges: */
     int i,n=2;
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
     CmiPrintf("[%d] Trying to split bad address space at %p - %p...\n",CmiMyPe(),start,end);
 #endif
     len=divide_range(len,n);
@@ -1821,7 +1816,7 @@ static void check_range(char *start,char *end,memRegion_t *max)
   }
   else /* range is good */
   { 
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
     CmiPrintf("[%d] Address space at %p - %p is largest\n",CmiMyPe(),start,end);
 #endif
 
@@ -1927,7 +1922,7 @@ static int find_largest_free_region(memRegion_t *destRegion) {
 #if CMK_MACOSX
     if (regions[i].start+regions[i].len*2>regions[i].start) regions[i].len *= 2;
 #endif
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
     CmiPrintf("[%d] Memory map: %p - %p (len: %lu => %lu) %s \n",CmiMyPe(),
         regions[i].start,regions[i].start+regions[i].len,
         old.len, regions[i].len, regions[i].type);
@@ -1973,7 +1968,7 @@ static int try_largest_mmap_region(memRegion_t *destRegion)
     range = bad_alloc;
 #endif
     if (range == bad_alloc) {  /* mmap failed */
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
       /* CmiPrintf("[%d] test failed at size: %llu error: %d\n", CmiMyPe(), size, errno);  */
 #endif
 #if CMK_HAS_USLEEP
@@ -1984,7 +1979,7 @@ static int try_largest_mmap_region(memRegion_t *destRegion)
       if (size<=0) return 0; /* mmap doesn't work */
     }
     else { /* this allocation size is available */
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
       CmiPrintf("[%d] available: %p, %lld\n", CmiMyPe(), range, size);
 #endif
       call_munmap(range,size); /* needed/wanted? */
@@ -2000,7 +1995,7 @@ static int try_largest_mmap_region(memRegion_t *destRegion)
   CmiAssert(good_range!=NULL);
   destRegion->start=good_range; 
   destRegion->len=good_size;
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
   pid_t pid = getpid();
   {
     char s[128];
@@ -2024,7 +2019,11 @@ static void init_ranges(char **argv)
   int pagesize = 0;
 
   /*Round slot size up to nearest page size*/
+#if CMK_USE_MEMPOOL_ISOMALLOC
+  slotsize=1024*1024;
+#else
   slotsize=16*1024;
+#endif 
 #if CMK_HAS_GETPAGESIZE
   pagesize = getpagesize();
 #endif
@@ -2032,7 +2031,7 @@ static void init_ranges(char **argv)
     pagesize = CMK_MEMORY_PAGESIZE;
   slotsize=(slotsize+pagesize-1) & ~(pagesize-1);
 
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
   if (CmiMyPe() == 0)
     CmiPrintf("[%d] Using slotsize of %d\n", CmiMyPe(), slotsize);
 #endif
@@ -2065,16 +2064,14 @@ static void init_ranges(char **argv)
     }
     else /* freeRegion.len>0, so can isomalloc */
     {
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
       CmiPrintf("[%d] Isomalloc memory region: %p - %p (%d megs)\n",CmiMyPe(),
           freeRegion.start,freeRegion.start+freeRegion.len,
           freeRegion.len/meg);
 #endif
     }
   }             /* end if myrank == 0 */
-
   CmiNodeAllBarrier();
-
   /*
      on some machines, isomalloc memory regions on different nodes 
      can be different. use +isomalloc_sync to calculate the
@@ -2082,18 +2079,47 @@ static void init_ranges(char **argv)
      */
   if (_sync_iso == 1)
   {
+#ifdef __FAULT__
+    if(_restart == 1){
+      CmiUInt8 s = (CmiUInt8)freeRegion.start;
+      CmiUInt8 e = (CmiUInt8)(freeRegion.start+freeRegion.len);
+      CmiUInt8 ss, ee;
+      int try_count, fd;
+      char fname[128];
+      sprintf(fname,".isomalloc");
+      try_count = 0;
+      while ((fd = open(fname, O_RDONLY)) == -1 && try_count<10000){
+        try_count++;
+      }
+      if (fd == -1) {
+        CmiAbort("isomalloc_sync failed during restart, make sure you have a shared file system.");
+      }
+      read(fd, &ss, sizeof(CmiUInt8));
+      read(fd, &ee, sizeof(CmiUInt8));
+      close(fd);
+      if (ss < s || ee > e)
+        CmiAbort("isomalloc_sync failed during restart, virtual memory regions do not overlap.");
+      else {
+        freeRegion.start = (void *)ss;
+        freeRegion.len = (char *)ee -(char *)ss;
+      }
+      CmiPrintf("[%d] consolidated Isomalloc memory region at restart: %p - %p (%d megs)\n",CmiMyPe(),freeRegion.start,freeRegion.start+freeRegion.len,freeRegion.len/meg);
+      goto AFTER_SYNC;
+    }
+#endif
     if (CmiMyRank() == 0 && freeRegion.len > 0u) {
       if (CmiBarrier() == -1 && CmiMyPe()==0) 
         CmiAbort("Charm++ Error> +isomalloc_sync requires CmiBarrier() implemented.\n");
-      else {
+      else
+      {
         CmiUInt8 s = (CmiUInt8)freeRegion.start;
         CmiUInt8 e = (CmiUInt8)(freeRegion.start+freeRegion.len);
-        int fd, i;
+        int fd, i,j;
         char fname[128];
 
         if (CmiMyNode()==0) printf("Charm++> synchronizing isomalloc memory region...\n");
 
-        sprintf(fname,".isomalloc.%d", CmiMyNode());
+        sprintf(fname,".isomalloc.%d.%d", CmiMyPartition(),CmiMyNode());
 
         /* remove file before writing for safe */
         unlink(fname);
@@ -2118,34 +2144,35 @@ static void init_ranges(char **argv)
 #endif
 
         CmiBarrier();
-
-        for (i=0; i<CmiNumNodes(); i++) {
-          CmiUInt8 ss, ee; 
-          int try_count;
-          char fname[128];
-          if (i==CmiMyNode()) continue;
-          sprintf(fname,".isomalloc.%d", i);
-          try_count = 0;
-          while ((fd = open(fname, O_RDONLY)) == -1 && try_count<10000)
-          {
-            try_count++;
+        for(j=0;j<CmiNumPartition();j++){
+          for (i=0; i<CmiNumNodes(); i++) {
+            CmiUInt8 ss, ee; 
+            int try_count;
+            char fname[128];
+            //if (i==CmiMyNode()) continue;
+            sprintf(fname,".isomalloc.%d.%d",j, i);
+            try_count = 0;
+            while ((fd = open(fname, O_RDONLY)) == -1 && try_count<10000)
+            {
+              try_count++;
 #ifndef __MINGW_H
-            CMK_CPV_IS_SMP
+              CMK_CPV_IS_SMP
 #endif
-              ;
-          }
-          if (fd == -1) {
-            CmiAbort("isomalloc_sync failed, make sure you have a shared file system.");
-          }
-          read(fd, &ss, sizeof(CmiUInt8));
-          read(fd, &ee, sizeof(CmiUInt8));
-#if CMK_THREADS_DEBUG
-          if (CmiMyPe() == 0) CmiPrintf("[%d] load node %d isomalloc region: %lx %lx. \n",
-              CmiMyPe(), i, ss, ee);
+                ;
+            }
+            if (fd == -1) {
+              CmiAbort("isomalloc_sync failed, make sure you have a shared file system.");
+            }
+            read(fd, &ss, sizeof(CmiUInt8));
+            read(fd, &ee, sizeof(CmiUInt8));
+#if ISOMALLOC_DEBUG
+            if (CmiMyPe() == 0) CmiPrintf("[%d] load node %d isomalloc region: %lx %lx. \n",
+                CmiMyPe(), i, ss, ee);
 #endif
-          close(fd);
-          if (ss>s) s = ss;
-          if (ee<e) e = ee;
+            close(fd);
+            if (ss>s) s = ss;
+            if (ee<e) e = ee;
+          }
         }
 
         CmiBarrier();
@@ -2167,6 +2194,19 @@ static void init_ranges(char **argv)
           CmiPrintf("[%d] consolidated Isomalloc memory region: %p - %p (%d megs)\n",CmiMyPe(),
               freeRegion.start,freeRegion.start+freeRegion.len,
               freeRegion.len/meg);
+#if __FAULT__
+        if(CmiMyPe() == 0 && CmiMyPartition() == 0){
+          int fd;
+          char fname[128];
+          CmiUInt8 s = (CmiUInt8)freeRegion.start;
+          CmiUInt8 e = (CmiUInt8)(freeRegion.start+freeRegion.len);
+          sprintf(fname,".isomalloc");
+          while ((fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0644)) == -1);
+          write(fd, &s, sizeof(CmiUInt8));
+          write(fd, &e, sizeof(CmiUInt8));
+          close(fd);
+        }
+#endif
       }   /* end of barrier test */
     } /* end of rank 0 */
     else {
@@ -2177,6 +2217,10 @@ static void init_ranges(char **argv)
     }
   }
 
+#ifdef __FAULT__
+AFTER_SYNC:
+#endif
+
   if (CmiMyRank() == 0 && freeRegion.len > 0u)
   {
     /*Isomalloc covers entire unused region*/
@@ -2184,7 +2228,7 @@ static void init_ranges(char **argv)
     isomallocEnd=freeRegion.start+freeRegion.len;
     numslots=(freeRegion.len/slotsize)/CmiNumPes();
 
-#if CMK_THREADS_DEBUG
+#if ISOMALLOC_DEBUG
     CmiPrintf("[%d] Can isomalloc up to %lu megs per pe\n",CmiMyPe(),
         ((memRange_t)numslots)*slotsize/meg);
 #endif
@@ -2196,7 +2240,7 @@ static void init_ranges(char **argv)
   CpvInitialize(slotset *, myss);
   CpvAccess(myss) = NULL;
 
-#if USE_MEMPOOL_ISOMALLOC
+#if CMK_USE_MEMPOOL_ISOMALLOC
   CtvInitialize(mempool_type *, threadpool);
   CtvAccess(threadpool) = NULL;
 #endif
@@ -2293,25 +2337,35 @@ static void all_slotOP(const slotOP *op,CmiInt8 s,CmiInt8 n)
 }
 
 /************** External interface ***************/
-#if USE_MEMPOOL_ISOMALLOC
-void *CmiIsomalloc(int size)
+#if CMK_USE_MEMPOOL_ISOMALLOC
+void *CmiIsomalloc(int size, CthThread tid)
 {
   CmiInt8 s,n,i;
   CmiIsomallocBlock *blk;
-  printf("[%d] isomalloc request for %d\n",CmiMyPe(),size);
   if (isomallocStart==NULL) return disabled_map(size);
-  if(CtvAccess(threadpool) == NULL) {
-    CtvAccess(threadpool) = mempool_init(size+sizeof(CmiIsomallocBlock), 
-                                                isomallocfn, isofreefn);
+  if(tid != NULL) {
+    if(CtvAccessOther(tid,threadpool) == NULL) {
+#if ISOMALLOC_DEBUG
+      printf("Init Mempool in %d for %d\n",CthSelf(), tid);
+#endif
+      CtvAccessOther(tid,threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn,0);
+    }
+    blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccessOther(tid,threadpool),size+sizeof(CmiIsomallocBlock),1);
+  } else {
+    if(CtvAccess(threadpool) == NULL) {
+#if ISOMALLOC_DEBUG
+      printf("Init Mempool in %d\n",CthSelf());
+#endif
+      CtvAccess(threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn,0);
+    }
+    blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccess(threadpool),size+sizeof(CmiIsomallocBlock),1);
   }
-  blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccess(threadpool),size+sizeof(CmiIsomallocBlock),1);
-  blk->slot=-1;
+  blk->slot=(CmiInt8)blk;
   blk->length=size;
-  printf("[%d] isomalloc request done for %d\n",CmiMyPe(),size);
   return block2pointer(blk);
 }
 #else
-void *CmiIsomalloc(int size)
+void *CmiIsomalloc(int size, CthThread tid)
 {
   CmiInt8 s,n,i;
   CmiIsomallocBlock *blk;
@@ -2346,8 +2400,7 @@ void *CmiIsomalloc(int size)
 /** return an aligned isomalloc memory, the alignment occurs after the
  *  first 'reserved' bytes.  Total requested size is (size+reserved)
  */
-static void *_isomallocAlign(size_t align, size_t size, size_t reserved)
-{
+static void *_isomallocAlign(size_t align, size_t size, size_t reserved, CthThread t) {
   void *ptr;
   CmiIntPtr ptr2align;
   CmiInt8 s;
@@ -2360,7 +2413,7 @@ static void *_isomallocAlign(size_t align, size_t size, size_t reserved)
     align = a;
   }
   s = size + reserved + align;
-  ptr = CmiIsomalloc(s);
+  ptr = CmiIsomalloc(s,t);
   ptr2align = (CmiIntPtr)ptr;
   ptr2align += reserved;
   if (ptr2align % align != 0) { /* misaligned */
@@ -2375,9 +2428,9 @@ static void *_isomallocAlign(size_t align, size_t size, size_t reserved)
   return ptr;
 }
 
-void *CmiIsomallocAlign(size_t align, size_t size)
+void *CmiIsomallocAlign(size_t align, size_t size, CthThread t)
 {
-  return _isomallocAlign(align, size, 0);
+  return _isomallocAlign(align, size, 0, t);
 }
 
 int CmiIsomallocEnabled()
@@ -2390,6 +2443,9 @@ void CmiIsomallocPup(pup_er p,void **blockPtrPtr)
   CmiIsomallocBlock *blk;
   CmiInt8 s,length;
   CmiInt8 n;
+#if CMK_USE_MEMPOOL_ISOMALLOC
+  CmiAbort("Incorrect pup is called\n");
+#endif
   if (isomallocStart==NULL) CmiAbort("isomalloc is disabled-- cannot use IsomallocPup");
 
   if (!pup_isUnpacking(p)) 
@@ -2433,8 +2489,8 @@ void CmiIsomallocFree(void *blockPtr)
   }
   else if (blockPtr!=NULL)
   {
-#if USE_MEMPOOL_ISOMALLOC
-    mempool_free(CtvAccess(threadpool), blockPtr);
+#if CMK_USE_MEMPOOL_ISOMALLOC
+    mempool_free_thread((void*)pointer2block(blockPtr)->slot);
 #else
     CmiIsomallocBlock *blk=pointer2block(blockPtr);
     CmiInt8 s=blk->slot; 
@@ -2479,6 +2535,11 @@ void CmiIsomallocInit(char **argv)
     _mmap_probe = 0;
   if (CmiGetArgFlagDesc(argv,"+isomalloc_sync","synchronize isomalloc region globaly"))
     _sync_iso = 1;
+#if __FAULT__
+  int resPhase;
+  if (CmiGetArgFlagDesc(argv,"+restartisomalloc","restarting isomalloc on this processor after a crash"))
+    _restart = 1;
+#endif
   init_comm(argv);
   if (!init_map(argv)) {
     disable_isomalloc("mmap() does not work");
@@ -2508,10 +2569,10 @@ static char *Slot_toUser(CmiIsomallocBlockList *s) {return (char *)(s+1);}
 static CmiIsomallocBlockList *Slot_fmUser(void *s) {return ((CmiIsomallocBlockList *)s)-1;}
 
 /*Build a new blockList.*/
-CmiIsomallocBlockList *CmiIsomallocBlockListNew(void)
+CmiIsomallocBlockList *CmiIsomallocBlockListNew(CthThread tid)
 {
   CmiIsomallocBlockList *ret;
-  ret=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(*ret));
+  ret=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(*ret),tid);
   ret->next=ret; /*1-entry circular linked list*/
   ret->prev=ret;
   return ret;
@@ -2524,140 +2585,250 @@ static void print_myslots();
   list traversals.  Because everything's isomalloc'd, we don't even
   have to restore the pointers-- they'll be restored automatically!
   */
-#if USE_MEMPOOL_ISOMALLOC
-void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp)
+#if CMK_USE_MEMPOOL_ISOMALLOC
+void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid)
 {
-  mempool_block *current, *mempools_head;
+  mempool_type *mptr;
+  block_header *current, *block_head;
+  slot_header *currSlot;
   void *newblock;
   CmiInt8 slot;
-  CmiInt8 size;
+  size_t size;
+  int flags[2];
+  int i, j;
+  int numBlocks = 0, numSlots = 0, flag = 1;
 
-  if(!pup_isUnpacking(p)) {
-    printf("[%d] address is %p %p\n",CmiMyPe(),CtvAccess(threadpool),&(CtvAccess(threadpool)->mempools_head));
-    current = &(CtvAccess(threadpool)->mempools_head);
+#if ISOMALLOC_DEBUG
+  printf("[%d] My rank is %lld Pupping for %lld with isUnpack %d isDelete %d \n",CmiMyPe(),CthSelf(),tid,pup_isUnpacking(p),pup_isDeleting(p));
+#endif
+  flags[0] = 0; flags[1] = 1;
+  //  if(!pup_isUnpacking(p)&& !pup_isChecking(p)) {
+  int first = 1;
+  i = 0; j = 0;
+  //if(!pup_isUnpacking(p)) {
+  if(!pup_isUnpacking(p)&&!(pup_isChecking(p)&&!pup_isCalChecking(p))) {
+    mptr = CtvAccessOther(tid,threadpool);
+    current = MEMPOOL_GetBlockHead(mptr);
     while(current != NULL) {
-      pup_int8(p,&current->size);
-      pup_int8(p,&current->mem_hndl);
-      pup_bytes(p,current->mempool_ptr,current->size);
-      printf("[%d] Packing slot %lld size %lld at %p to %p\n",CmiMyPe(),current->mem_hndl,current->size,current->mempool_ptr,current->mempool_ptr+current->size);
-      current = current->next;
+      numBlocks++;
+      current = MEMPOOL_GetBlockNext(current)?(block_header *)((char*)mptr+MEMPOOL_GetBlockNext(current)):NULL;
+    }
+#if ISOMALLOC_DEBUG
+    printf("Number of blocks packed %d\n",numBlocks);
+#endif
+    pup_int(p,&numBlocks);
+    current = MEMPOOL_GetBlockHead(mptr);
+    while(current != NULL) {
+      j=0;
+      pup_bytes(p,&(MEMPOOL_GetBlockSize(current)),sizeof(MEMPOOL_GetBlockSize(current)));
+      pup_bytes(p,&(MEMPOOL_GetBlockMemHndl(current)),sizeof(CmiInt8));
+      numSlots = 0;
+      if(flag) {
+        pup_bytes(p,current,sizeof(mempool_type));
+        currSlot = (slot_header*)((char*)current+sizeof(mempool_type));
+      } else {
+        pup_bytes(p,current,sizeof(block_header));
+        currSlot = (slot_header*)((char*)current+sizeof(block_header));
+      }
+      while(currSlot != NULL) {
+        numSlots++;
+        currSlot = (MEMPOOL_GetSlotGNext(currSlot))?(slot_header*)((char*)mptr+MEMPOOL_GetSlotGNext(currSlot)):NULL;
+      }
+      pup_int(p,&numSlots);
+      if(flag) {
+        currSlot = (slot_header*)((char*)current+sizeof(mempool_type));
+        flag = 0;
+      } else {
+        currSlot = (slot_header*)((char*)current+sizeof(block_header));
+      }
+      while(currSlot != NULL) {
+        pup_int(p,&cutOffPoints[currSlot->size]);
+        if(MEMPOOL_GetSlotStatus(currSlot)) {
+          pup_int(p,&flags[0]);
+          pup_bytes(p,(void*)currSlot,sizeof(slot_header));
+        } else {
+          pup_int(p,&flags[1]);
+          //pup_bytes(p,(void*)currSlot,sizeof(slot_header));
+          if(pup_isChecking(p)){
+            if(first == 0){
+              pup_resumeChecking(p);
+            }else{
+              first = 0;
+            }
+            //      printf("[%d][%d]checking block %d slot %d check isomalloc header %d\n",CmiMyPartition(),CmiMyPe(),i,j,MEMPOOL_GetSlotSize(currSlot));
+          }
+          //         else
+          //         printf("[%d][%d]block %d slot %d check isomalloc header %d\n",CmiMyPartition(),CmiMyPe(),i,j,MEMPOOL_GetSlotSize(currSlot));
+          //pup_bytes(p,(void*)currSlot+sizeof(slot_header),MEMPOOL_GetSlotSize(currSlot)-sizeof(slot_header));
+          pup_bytes(p,(void*)currSlot,MEMPOOL_GetSlotSize(currSlot));
+          if(pup_isChecking(p)){
+            pup_skipChecking(p);
+          }
+        }
+        currSlot = (MEMPOOL_GetSlotGNext(currSlot))?(slot_header*)((char*)mptr+MEMPOOL_GetSlotGNext(currSlot)):NULL;
+        j++;
+      }
+      current = (MEMPOOL_GetBlockNext(current))?(block_header *)((char*)mptr+MEMPOOL_GetBlockNext(current)):NULL;
+      i++;
     }
   }
 
-  if(pup_isUnpacking(p)) {
-    pup_int8(p,&size);
-    pup_int8(p,&slot);
-    newblock = map_slots(slot,size/slotsize);
-    pup_bytes(p,newblock,size);
-    printf("[%d] slot %lld size %lld at %p to %p\n",CmiMyPe(),slot,size,newblock,newblock+size);
+  if(pup_isUnpacking(p)||(pup_isChecking(p)&&!pup_isCalChecking(p))) {
+    //if(pup_isUnpacking(p)) {
+    pup_int(p,&numBlocks);
+#if ISOMALLOC_DEBUG
+    printf("Number of blocks to be unpacked %d\n",numBlocks);
+#endif
+    //printf("[%d][%d]Number of blocks to be unpacked %d\n",CmiMyPartition(),CmiMyPe(),numBlocks);
+    for(i = 0; i < numBlocks; i++) { 
+      pup_bytes(p,&size,sizeof(size));
+      pup_bytes(p,&slot,sizeof(slot));
+      newblock = map_slots(slot,size/slotsize);
+      if(flag) {
+        mptr = (mempool_type*)newblock;
+        pup_bytes(p,newblock,sizeof(mempool_type));
+        newblock = (char*)newblock + sizeof(mempool_type);
+        flag = 0;
+      } else {
+        pup_bytes(p,newblock,sizeof(block_header));
+        newblock = (char*)newblock + sizeof(block_header);
+      }
+      pup_int(p,&numSlots);
+      //printf("[%d][%d]Number of slots to be unpacked %d\n",CmiMyPartition(),CmiMyPe(),numSlots);
+      for(j=0; j < numSlots; j++) {
+        pup_int(p,&flags[0]);
+        pup_int(p,&flags[1]);
+        if(flags[1] == 0) {
+          pup_bytes(p,newblock,sizeof(slot_header));
+        } else {
+          //pup_bytes(p,newblock,sizeof(slot_header));
+          if(pup_isChecking(p)){
+            if(first == 0){
+              pup_resumeChecking(p);
+            }else{
+              first = 0;
+            }
+            //       printf("[%d][%d]unpack block %d slot %d check isomalloc header %d\n",CmiMyPartition(),CmiMyPe(),i,j,flags[0]);
+          }
+          pup_bytes(p,newblock,flags[0]);
+          if(pup_isChecking(p)){
+            pup_skipChecking(p);
+          }
+        }
+        newblock = (char*)newblock + flags[0];
+      }
+    }
+#if CMK_USE_MEMPOOL_ISOMALLOC || (CMK_SMP && CMK_CONVERSE_GEMINI_UGNI)
+    mptr->mempoolLock = CmiCreateLock();
+#endif  
   }
   pup_bytes(p,lp,sizeof(int*));
   if(pup_isDeleting(p)) {
-    mempool_destroy(CtvAccess(threadpool));
+    mempool_destroy(CtvAccessOther(tid,threadpool));
     *lp=NULL;
   }
-}
+  }
 #else
-void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp)
-{
-  /* BIGSIM_OOC DEBUGGING */
-  /* if(!pup_isUnpacking(p)) print_myslots(); */
+  void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid)
+  {
+    /* BIGSIM_OOC DEBUGGING */
+    /* if(!pup_isUnpacking(p)) print_myslots(); */
 
-  int i,nBlocks=0;
-  CmiIsomallocBlockList *cur=NULL, *start=*lp;
+    int i,nBlocks=0;
+    CmiIsomallocBlockList *cur=NULL, *start=*lp;
 #if 0 /*#ifndef CMK_OPTIMIZE*/
-  if (CpvAccess(isomalloc_blocklist)!=NULL)
-    CmiAbort("Called CmiIsomallocBlockListPup while a blockList is active!\n"
-        "You should swap out the active blocklist before pupping.\n");
-#endif
-  /*Count the number of blocks in the list*/
-  if (!pup_isUnpacking(p)) {
-    nBlocks=1; /*<- Since we have to skip the start block*/
-    for (cur=start->next; cur!=start; cur=cur->next) 
-      nBlocks++;
-    /*Prepare for next trip around list:*/
-    cur=start;
-  }
-  pup_int(p,&nBlocks);
-
-  /*Pup each block in the list*/
-  for (i=0;i<nBlocks;i++) {
-    void *newBlock=cur;
-    if (!pup_isUnpacking(p)) 
-    { /*While packing, we traverse the list to find our blocks*/
-      cur=cur->next;
+    if (CpvAccess(isomalloc_blocklist)!=NULL)
+      CmiAbort("Called CmiIsomallocBlockListPup while a blockList is active!\n"
+          "You should swap out the active blocklist before pupping.\n");
+#endif
+    /*Count the number of blocks in the list*/
+    if (!pup_isUnpacking(p)) {
+      nBlocks=1; /*<- Since we have to skip the start block*/
+      for (cur=start->next; cur!=start; cur=cur->next) 
+        nBlocks++;
+      /*Prepare for next trip around list:*/
+      cur=start;
     }
-    CmiIsomallocPup(p,&newBlock);
-    if (i==0 && pup_isUnpacking(p))
-      *lp=(CmiIsomallocBlockList *)newBlock;
-  }
-  if (pup_isDeleting(p))
-    *lp=NULL;
+    pup_int(p,&nBlocks);
+
+    /*Pup each block in the list*/
+    for (i=0;i<nBlocks;i++) {
+      void *newBlock=cur;
+      if (!pup_isUnpacking(p)) 
+      { /*While packing, we traverse the list to find our blocks*/
+        cur=cur->next;
+      }
+      CmiIsomallocPup(p,&newBlock);
+      if (i==0 && pup_isUnpacking(p))
+        *lp=(CmiIsomallocBlockList *)newBlock;
+    }
+    if (pup_isDeleting(p))
+      *lp=NULL;
 
-  /* BIGSIM_OOC DEBUGGING */
-  /* if(pup_isUnpacking(p)) print_myslots(); */
-}
+    /* BIGSIM_OOC DEBUGGING */
+    /* if(pup_isUnpacking(p)) print_myslots(); */
+  }
 #endif
 
-/*Delete all the blocks in this list.*/
-void CmiIsomallocBlockListDelete(CmiIsomallocBlockList *l)
-{
-  CmiIsomallocBlockList *start=l;
-  CmiIsomallocBlockList *cur=start;
-  if (cur==NULL) return; /*Already deleted*/
-  do {
-    CmiIsomallocBlockList *doomed=cur;
-    cur=cur->next; /*Have to stash next before deleting cur*/
-    CmiIsomallocFree(doomed);
-  } while (cur!=start);
-}
-
-/*Allocate a block from this blockList*/
-void *CmiIsomallocBlockListMalloc(CmiIsomallocBlockList *l,size_t nBytes)
-{
-  CmiIsomallocBlockList *n; /*Newly created slot*/
-  n=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(CmiIsomallocBlockList)+nBytes);
-  /*Link the new block into the circular blocklist*/
-  n->prev=l;
-  n->next=l->next;
-  l->next->prev=n;
-  l->next=n;
-  return Slot_toUser(n);
-}
-
-/*Allocate a block from this blockList with alighment */
-void *CmiIsomallocBlockListMallocAlign(CmiIsomallocBlockList *l,size_t align,size_t nBytes)
-{
-  CmiIsomallocBlockList *n; /*Newly created slot*/
-  n=(CmiIsomallocBlockList *)_isomallocAlign(align,nBytes,sizeof(CmiIsomallocBlockList));
-  /*Link the new block into the circular blocklist*/
-  n->prev=l;
-  n->next=l->next;
-  l->next->prev=n;
-  l->next=n;
-  return Slot_toUser(n);
-}
-
-/*Remove this block from its list and memory*/
-void CmiIsomallocBlockListFree(void *block)
-{
-  CmiIsomallocBlockList *n=Slot_fmUser(block);
+  /*Delete all the blocks in this list.*/
+  void CmiIsomallocBlockListDelete(CmiIsomallocBlockList *l)
+  {
+    CmiIsomallocBlockList *start=l;
+    CmiIsomallocBlockList *cur=start;
+    if (cur==NULL) return; /*Already deleted*/
+    do {
+      CmiIsomallocBlockList *doomed=cur;
+      cur=cur->next; /*Have to stash next before deleting cur*/
+      CmiIsomallocFree(doomed);
+    } while (cur!=start);
+  }
+
+  /*Allocate a block from this blockList*/
+  void *CmiIsomallocBlockListMalloc(CmiIsomallocBlockList *l,size_t nBytes)
+  {
+    CmiIsomallocBlockList *n; /*Newly created slot*/
+    n=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(CmiIsomallocBlockList)+nBytes,NULL);
+    /*Link the new block into the circular blocklist*/
+    n->prev=l;
+    n->next=l->next;
+    l->next->prev=n;
+    l->next=n;
+    return Slot_toUser(n);
+  }
+
+  /*Allocate a block from this blockList with alighment */
+  void *CmiIsomallocBlockListMallocAlign(CmiIsomallocBlockList *l,size_t align,size_t nBytes)
+  {
+    CmiIsomallocBlockList *n; /*Newly created slot*/
+    n=(CmiIsomallocBlockList *)_isomallocAlign(align,nBytes,sizeof(CmiIsomallocBlockList),NULL);
+    /*Link the new block into the circular blocklist*/
+    n->prev=l;
+    n->next=l->next;
+    l->next->prev=n;
+    l->next=n;
+    return Slot_toUser(n);
+  }
+
+  /*Remove this block from its list and memory*/
+  void CmiIsomallocBlockListFree(void *block)
+  {
+    CmiIsomallocBlockList *n=Slot_fmUser(block);
 #if DOHEAPCHECK
-  if (n->prev->next!=n || n->next->prev!=n) 
-    CmiAbort("Heap corruption detected in isomalloc block list header!\n"
-        "  Run with ++debug and look for writes to negative array indices");
+    if (n->prev->next!=n || n->next->prev!=n) 
+      CmiAbort("Heap corruption detected in isomalloc block list header!\n"
+          "  Run with ++debug and look for writes to negative array indices");
 #endif
-  /*Link ourselves out of the blocklist*/
-  n->prev->next=n->next;
-  n->next->prev=n->prev;
-  CmiIsomallocFree(n);
-}
+    /*Link ourselves out of the blocklist*/
+    n->prev->next=n->next;
+    n->next->prev=n->prev;
+    CmiIsomallocFree(n);
+  }
 
-/* BIGSIM_OOC DEBUGGING */
-static void print_myslots(){
-  CmiPrintf("[%d] my slot set=%p\n", CmiMyPe(), CpvAccess(myss));
-  print_slots(CpvAccess(myss));
-}
+  /* BIGSIM_OOC DEBUGGING */
+  static void print_myslots(){
+    CmiPrintf("[%d] my slot set=%p\n", CmiMyPe(), CpvAccess(myss));
+    print_slots(CpvAccess(myss));
+  }