fix for migration
[charm.git] / src / conv-core / isomalloc.c
index 85106d1126c5096ece66c82c5f8082478d2b6c20..e784d44271d99d39c60676cc0a6aad446853911e 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$ 
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 /**************************************************************************
 Isomalloc:
 A way to allocate memory at the same address on every processor.
@@ -69,9 +62,13 @@ added by Ryan Mokos in July 2008.
 
 #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)
@@ -1647,7 +1644,7 @@ static void map_failed(CmiInt8 s,CmiInt8 n)
 CpvStaticDeclare(slotset *, myss); /*My managed slots*/
 
 #if CMK_USE_MEMPOOL_ISOMALLOC
-CtvStaticDeclare(mempool_type *, threadpool); /*Thread managed pools*/
+CtvDeclare(mempool_type *, threadpool); /*Thread managed pools*/
 
 //alloc function to be used by mempool
 void * isomallocfn (size_t *size, mem_handle_t *mem_hndl, int expand_flag)
@@ -1659,7 +1656,7 @@ void * isomallocfn (size_t *size, mem_handle_t *mem_hndl, int expand_flag)
   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);
@@ -2074,9 +2071,7 @@ static void init_ranges(char **argv)
 #endif
     }
   }             /* end if myrank == 0 */
-
   CmiNodeAllBarrier();
-
   /*
      on some machines, isomalloc memory regions on different nodes 
      can be different. use +isomalloc_sync to calculate the
@@ -2084,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);
@@ -2120,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 (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);
+            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();
@@ -2169,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 {
@@ -2179,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*/
@@ -2306,7 +2348,7 @@ void *CmiIsomalloc(int size, CthThread tid)
 #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);
+      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 {
@@ -2314,7 +2356,7 @@ void *CmiIsomalloc(int size, CthThread tid)
 #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);
+      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);
   }
@@ -2493,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");
@@ -2545,30 +2592,36 @@ void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid
   block_header *current, *block_head;
   slot_header *currSlot;
   void *newblock;
-  CmiInt8 slot,size;
+  CmiInt8 slot;
+  size_t size;
   int flags[2];
   int i, j;
   int numBlocks = 0, numSlots = 0, flag = 1;
 
-  flags[0] = 0; flags[1] = 1;
-  if(!pup_isUnpacking(p)) {
 #if ISOMALLOC_DEBUG
-    printf("My rank is %d Pupping for %d \n",CthSelf(),tid);
+  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 = &(CtvAccessOther(tid,threadpool)->block_head);
+    current = MEMPOOL_GetBlockHead(mptr);
     while(current != NULL) {
       numBlocks++;
-      current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
+      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 = &(CtvAccessOther(tid,threadpool)->block_head);
+    current = MEMPOOL_GetBlockHead(mptr);
     while(current != NULL) {
-      pup_int8(p,&current->size);
-      pup_bytes(p,&current->mem_hndl,sizeof(CmiInt8));
+      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));
@@ -2579,7 +2632,7 @@ void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid
       }
       while(currSlot != NULL) {
         numSlots++;
-        currSlot = currSlot->gnext?(slot_header*)((char*)mptr+currSlot->gnext):NULL;
+        currSlot = (MEMPOOL_GetSlotGNext(currSlot))?(slot_header*)((char*)mptr+MEMPOOL_GetSlotGNext(currSlot)):NULL;
       }
       pup_int(p,&numSlots);
       if(flag) {
@@ -2589,30 +2642,50 @@ void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid
         currSlot = (slot_header*)((char*)current+sizeof(block_header));
       }
       while(currSlot != NULL) {
-        pup_int(p,&currSlot->size);
-        if(currSlot->status) {
+        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,currSlot->size);
+          //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 = currSlot->gnext?(slot_header*)((char*)mptr+currSlot->gnext):NULL;
+        currSlot = (MEMPOOL_GetSlotGNext(currSlot))?(slot_header*)((char*)mptr+MEMPOOL_GetSlotGNext(currSlot)):NULL;
+        j++;
       }
-      current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
+      current = (MEMPOOL_GetBlockNext(current))?(block_header *)((char*)mptr+MEMPOOL_GetBlockNext(current)):NULL;
+      i++;
     }
   }
 
-  if(pup_isUnpacking(p)) {
+  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_int8(p,&size);
-      pup_bytes(p,&slot,sizeof(CmiInt8));
+      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;
@@ -2621,125 +2694,141 @@ void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid
         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(CtvAccessOther(tid,threadpool));
     *lp=NULL;
   }
-}
+  }
 #else
-void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid)
-{
-  /* 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,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);
+  /*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));
+  }