fix for migration
[charm.git] / src / conv-core / isomalloc.c
index c71e02f7808eafcb5525891b4de0604a62635179..e784d44271d99d39c60676cc0a6aad446853911e 100644 (file)
@@ -1,36 +1,46 @@
-/*****************************************************************************
- * $Source$
- * $Author$ 
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 /**************************************************************************
 Isomalloc:
-  A way to allocate memory at the same address on every processor.
+A way to allocate memory at the same address on every processor.
 This enables linked data structures, like thread stacks, to be migrated
 to the same address range on other processors.  This is similar to an
 explicitly managed shared memory system.
 
-  The memory is used and released via the mmap()/mumap() calls, so unused
+The memory is used and released via the mmap()/mumap() calls, so unused
 memory does not take any (RAM, swap or disk) space.
 
-  The way it's implemented is that each processor claims some section 
+The way it's implemented is that each processor claims some section 
 of the available virtual address space, and satisfies all new allocations
 from that space.  Migrating structures use whatever space they started with.
 
+The b-tree implementation has two data structures that are maintained
+simultaneously and in conjunction with each other: a b-tree of nodes
+containing slotblocks used for quickly finding a particular slotblock;
+and an array of doubly-linked lists containing the same slotblocks,
+ordered according to the number of free slots in each slotblock, which
+is used for quickly finding a block of free slots of a desired size.
+The slotset contains pointers to both structures.
+print_btree_top_down() and print_list_array() are very useful
+functions for viewing the current structure of the tree and lists.
+
+Each doubly-linked list has slotblocks containing between 2^(n-1)+1
+and 2^n free slots, where n is the array index (i.e., bin number).
+For example, list_array[0] points to a double-linked list of
+slotblocks with 1 free slot, list_array[1] points to a double-linked
+list of slotblocks with 2 free slots, list_array[2] to slotblocks with
+3-4 free slots, list_array[3] to slotblocks with 5-8 free slots, etc.
+
 Written for migratable threads by Milind Bhandarkar around August 2000;
 generalized by Orion Lawlor November 2001.  B-tree implementation
 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)  */
+1: use the new isomalloc implementation (b-tree)  */
 #define USE_BTREE_ISOMALLOC 1
 
 /* b-tree definitions */
@@ -44,18 +54,27 @@ added by Ryan Mokos in July 2008.
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h> /* just so I can find dynamically-linked symbols */
-
-static int _sync_iso = 0;
+#include <unistd.h>
 
 #if CMK_HAS_ADDR_NO_RANDOMIZE
 #include <sys/personality.h>
 #endif
 
+#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)
 {
   FILE *fp;
   int random_flag;
-  CmiLock(smp_mutex);
   fp = fopen("/proc/sys/kernel/randomize_va_space", "r");
   if (fp != NULL) {
     fscanf(fp, "%d", &random_flag);
@@ -63,31 +82,30 @@ static int read_randomflag(void)
 #if CMK_HAS_ADDR_NO_RANDOMIZE
     if(random_flag)
     {
-       int persona = personality(0xffffffff);
-       if(persona & ADDR_NO_RANDOMIZE)
-           random_flag = 0;
+      int persona = personality(0xffffffff);
+      if(persona & ADDR_NO_RANDOMIZE)
+        random_flag = 0;
     }
 #endif
   }
   else {
     random_flag = -1;
   }
-  CmiUnlock(smp_mutex);
   return random_flag;
 }
 
 struct CmiIsomallocBlock {
-      CmiInt8 slot;   /* First mapped slot */
-      CmiInt8 length; /* Length of (user portion of) mapping, in bytes*/
+  CmiInt8 slot;   /* First mapped slot */
+  CmiInt8 length; /* Length of (user portion of) mapping, in bytes*/
 };
 typedef struct CmiIsomallocBlock CmiIsomallocBlock;
 
 /* Convert a heap block pointer to/from a CmiIsomallocBlock header */
 static void *block2pointer(CmiIsomallocBlock *blockHeader) {
-       return (void *)(blockHeader+1);
+  return (void *)(blockHeader+1);
 }
 static CmiIsomallocBlock *pointer2block(void *heapBlock) {
-       return ((CmiIsomallocBlock *)heapBlock)-1;
+  return ((CmiIsomallocBlock *)heapBlock)-1;
 }
 
 /* Integral type to be used for pointer arithmetic: */
@@ -95,32 +113,37 @@ typedef size_t memRange_t;
 
 /* Size in bytes of a single slot */
 static size_t slotsize;
+static size_t regionSize;
 
 /* Total number of slots per processor */
 static CmiInt8 numslots=0;
 
 /* Start and end of isomalloc-managed addresses.
    If isomallocStart==NULL, isomalloc is disabled.
-*/
+   */
 static char *isomallocStart=NULL;
 static char *isomallocEnd=NULL;
 
 /* Utility conversion functions */
 static void *slot2addr(CmiInt8 slot) {
-       return isomallocStart+((memRange_t)slotsize)*((memRange_t)slot);
+  return isomallocStart+((memRange_t)slotsize)*((memRange_t)slot);
 }
 static int slot2pe(CmiInt8 slot) {
-       return (int)(slot/numslots);
+  return (int)(slot/numslots);
 }
 static CmiInt8 pe2slot(int pe) {
-       return pe*numslots;
+  return pe*numslots;
 }
 /* Return the number of slots in a block with n user data bytes */
+#if CMK_USE_MEMPOOL_ISOMALLOC
 static int length2slots(int nBytes) {
-       return (sizeof(CmiIsomallocBlock)+nBytes+slotsize-1)/slotsize;
+  return (nBytes+slotsize-1)/slotsize;
 }
-
-
+#else
+static int length2slots(int nBytes) {
+  return (sizeof(CmiIsomallocBlock)+nBytes+slotsize-1)/slotsize;
+}
+#endif
 /* ======================================================================
  * New isomalloc (b-tree-based implementation)
  * ====================================================================== */
@@ -184,14 +207,14 @@ static int find_list_bin(CmiInt8 nslots) {
       list_bin -= inc;
       comp_num  = comp_num >> inc;
       if ((inc = inc >> 1) == 0) {
-       inc = 1;
+        inc = 1;
       }
     } else {
       /* look right */
       list_bin += inc;
       comp_num  = comp_num << inc;
       if ((inc = inc >> 1) == 0) {
-       inc = 1;
+        inc = 1;
       }
     }
   }
@@ -269,12 +292,12 @@ static void list_move(slotset *ss, dllnode *dlln, CmiInt8 old_nslots) {
     /* remove from old bin */
     if (dlln->previous == NULL) {  /* dlln is the 1st element in the list */
       if (dlln->next != NULL) {
-       dlln->next->previous = NULL;
+        dlln->next->previous = NULL;
       }
       ss->list_array[old_bin] = dlln->next;
     } else {
       if (dlln->next != NULL) {
-       dlln->next->previous = dlln->previous;
+        dlln->next->previous = dlln->previous;
       }
       dlln->previous->next = dlln->next;
     }
@@ -331,66 +354,66 @@ static slotblock *find_btree_slotblock(btreenode *node, CmiInt8 startslot) {
       /* if startslot is in current slotblock, this is the slotblock */
       endslot = node->blocks[index].startslot + node->blocks[index].nslots - 1;
       if ((startslot >= node->blocks[index].startslot) &&
-         (startslot <= endslot)) {
-       return &(node->blocks[index]);
+          (startslot <= endslot)) {
+        return &(node->blocks[index]);
       }
 
       /* else, if startslot is less */
       else if (startslot < node->blocks[index].startslot) {
 
-       /* if this is slotblock 0, take the left child */
-       if (index == 0) {
-         return find_btree_slotblock(node->child[index], startslot);
-       }
-
-       /* else check endslot of the slotblock to the left */
-       else {
-
-         /* if startslot > endslot-of-slotblock-to-the-left, take the
-            left child */
-         endslot = node->blocks[index-1].startslot + 
-           node->blocks[index-1].nslots - 1;
-         if (startslot > endslot) {
-           return find_btree_slotblock(node->child[index], startslot);
-         }
-
-         /* else continue to search this node to the left */
-         else {
-           index -= inc;
-           if ((inc = inc >> 1) == 0) {
-             inc = 1;
-           }
-         }
-       }
+        /* if this is slotblock 0, take the left child */
+        if (index == 0) {
+          return find_btree_slotblock(node->child[index], startslot);
+        }
+
+        /* else check endslot of the slotblock to the left */
+        else {
+
+          /* if startslot > endslot-of-slotblock-to-the-left, take the
+             left child */
+          endslot = node->blocks[index-1].startslot + 
+            node->blocks[index-1].nslots - 1;
+          if (startslot > endslot) {
+            return find_btree_slotblock(node->child[index], startslot);
+          }
+
+          /* else continue to search this node to the left */
+          else {
+            index -= inc;
+            if ((inc = inc >> 1) == 0) {
+              inc = 1;
+            }
+          }
+        }
       }
 
       /* else, startslot must be greater */
       else {
 
-       /* if this is the last slotblock, take the right child */
-       if (index == node->num_blocks - 1) {
-         return find_btree_slotblock(node->child[index+1], startslot);
-       }
-
-       /* else check startslot of the slotblock to the right */
-       else {
-
-         /* if startslot < startslot-of-slotblock-to-the-right, then
-            take the right child */
-         if (startslot < node->blocks[index+1].startslot) {
-           return find_btree_slotblock(node->child[index+1], startslot);
-         }
-
-         /* else continue to search this node to the right */
-         else {
-           index += inc;
-           if ((inc = inc >> 1) == 0) {
-             inc = 1;
-           }
-         }
-       }
+        /* if this is the last slotblock, take the right child */
+        if (index == node->num_blocks - 1) {
+          return find_btree_slotblock(node->child[index+1], startslot);
+        }
+
+        /* else check startslot of the slotblock to the right */
+        else {
+
+          /* if startslot < startslot-of-slotblock-to-the-right, then
+             take the right child */
+          if (startslot < node->blocks[index+1].startslot) {
+            return find_btree_slotblock(node->child[index+1], startslot);
+          }
+
+          /* else continue to search this node to the right */
+          else {
+            index += inc;
+            if ((inc = inc >> 1) == 0) {
+              inc = 1;
+            }
+          }
+        }
       }
-      
+
     }
 
   }
@@ -403,7 +426,7 @@ static slotblock *find_btree_slotblock(btreenode *node, CmiInt8 startslot) {
  *****************************************************************/
 
 static insert_ret_val btree_insert_int(slotset *ss, btreenode *node, 
-                                      CmiInt8 startslot, CmiInt8 nslots) {
+    CmiInt8 startslot, CmiInt8 nslots) {
 
   insert_ret_val irv;
 
@@ -417,179 +440,179 @@ static insert_ret_val btree_insert_int(slotset *ss, btreenode *node,
   while (1) {
     if (startslot < node->blocks[index].startslot) {  /* look to the left */
       if ((index == 0) || 
-         (startslot > node->blocks[index-1].startslot)) {
-       if (node->child[index] != NULL) {             /* take left child */
-         irv = btree_insert_int(ss, node->child[index], startslot, nslots);
-         if (irv.btn == NULL) {
-           return irv;
-         } else {                                    /* merge return value */
-           int i, j;                                 /*   insert on left   */
-           for (i = node->num_blocks; i > index; i--) {
-             node->blocks[i].startslot     = node->blocks[i-1].startslot;
-             node->blocks[i].nslots        = node->blocks[i-1].nslots;
-             node->blocks[i].listblock     = node->blocks[i-1].listblock;
-             node->blocks[i].listblock->sb = &(node->blocks[i]);
-             node->child[i+1]              = node->child[i];
-           }
-           node->blocks[index].startslot     = irv.sb.startslot;
-           node->blocks[index].nslots        = irv.sb.nslots;
-           node->blocks[index].listblock     = irv.sb.listblock;
-           node->blocks[index].listblock->sb = &(node->blocks[index]);
-           node->child[index+1]              = irv.btn;
-           node->num_blocks++;
-           if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
-             btreenode *new_node = create_btree_node();
-             for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
-               j = i - (TREE_NODE_MID + 1);
-               new_node->blocks[j].startslot     = node->blocks[i].startslot;
-               new_node->blocks[j].nslots        = node->blocks[i].nslots;
-               new_node->blocks[j].listblock     = node->blocks[i].listblock;
-               new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
-             }
-             for (i = TREE_NODE_MID + 1; i <= TREE_NODE_SIZE; i++) {
-               new_node->child[i-(TREE_NODE_MID+1)] = node->child[i];
-             }
-             node->num_blocks     = TREE_NODE_MID;
-             new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
-
-             irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
-             irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
-             irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
-             irv.btn          = new_node;
-             return irv;
-           } else {
-             irv.btn = NULL;
-             return irv;
-           }
-         }
-       } else {                                      /* insert to the left */
-         int i, j;
-         for (i = node->num_blocks; i > index; i--) {
-           node->blocks[i].startslot     = node->blocks[i-1].startslot;
-           node->blocks[i].nslots        = node->blocks[i-1].nslots;
-           node->blocks[i].listblock     = node->blocks[i-1].listblock;
-           node->blocks[i].listblock->sb = &(node->blocks[i]);
-         }
-         node->blocks[index].startslot = startslot;
-         node->blocks[index].nslots    = nslots;
-         node->blocks[index].listblock = list_insert(ss, &(node->blocks[index]));
-         node->num_blocks++;
-         if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
-           btreenode *new_node = create_btree_node();
-           for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
-             j = i - (TREE_NODE_MID + 1);
-             new_node->blocks[j].startslot     = node->blocks[i].startslot;
-             new_node->blocks[j].nslots        = node->blocks[i].nslots;
-             new_node->blocks[j].listblock     = node->blocks[i].listblock;
-             new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
-           }
-           node->num_blocks     = TREE_NODE_MID;
-           new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
-
-           irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
-           irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
-           irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
-           irv.btn          = new_node;
-           return irv;
-         } else {
-           irv.btn = NULL;
-           return irv;
-         }
-       }
+          (startslot > node->blocks[index-1].startslot)) {
+        if (node->child[index] != NULL) {             /* take left child */
+          irv = btree_insert_int(ss, node->child[index], startslot, nslots);
+          if (irv.btn == NULL) {
+            return irv;
+          } else {                                    /* merge return value */
+            int i, j;                                 /*   insert on left   */
+            for (i = node->num_blocks; i > index; i--) {
+              node->blocks[i].startslot     = node->blocks[i-1].startslot;
+              node->blocks[i].nslots        = node->blocks[i-1].nslots;
+              node->blocks[i].listblock     = node->blocks[i-1].listblock;
+              node->blocks[i].listblock->sb = &(node->blocks[i]);
+              node->child[i+1]              = node->child[i];
+            }
+            node->blocks[index].startslot     = irv.sb.startslot;
+            node->blocks[index].nslots        = irv.sb.nslots;
+            node->blocks[index].listblock     = irv.sb.listblock;
+            node->blocks[index].listblock->sb = &(node->blocks[index]);
+            node->child[index+1]              = irv.btn;
+            node->num_blocks++;
+            if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
+              btreenode *new_node = create_btree_node();
+              for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
+                j = i - (TREE_NODE_MID + 1);
+                new_node->blocks[j].startslot     = node->blocks[i].startslot;
+                new_node->blocks[j].nslots        = node->blocks[i].nslots;
+                new_node->blocks[j].listblock     = node->blocks[i].listblock;
+                new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
+              }
+              for (i = TREE_NODE_MID + 1; i <= TREE_NODE_SIZE; i++) {
+                new_node->child[i-(TREE_NODE_MID+1)] = node->child[i];
+              }
+              node->num_blocks     = TREE_NODE_MID;
+              new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
+
+              irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
+              irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
+              irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
+              irv.btn          = new_node;
+              return irv;
+            } else {
+              irv.btn = NULL;
+              return irv;
+            }
+          }
+        } else {                                      /* insert to the left */
+          int i, j;
+          for (i = node->num_blocks; i > index; i--) {
+            node->blocks[i].startslot     = node->blocks[i-1].startslot;
+            node->blocks[i].nslots        = node->blocks[i-1].nslots;
+            node->blocks[i].listblock     = node->blocks[i-1].listblock;
+            node->blocks[i].listblock->sb = &(node->blocks[i]);
+          }
+          node->blocks[index].startslot = startslot;
+          node->blocks[index].nslots    = nslots;
+          node->blocks[index].listblock = list_insert(ss, &(node->blocks[index]));
+          node->num_blocks++;
+          if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
+            btreenode *new_node = create_btree_node();
+            for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
+              j = i - (TREE_NODE_MID + 1);
+              new_node->blocks[j].startslot     = node->blocks[i].startslot;
+              new_node->blocks[j].nslots        = node->blocks[i].nslots;
+              new_node->blocks[j].listblock     = node->blocks[i].listblock;
+              new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
+            }
+            node->num_blocks     = TREE_NODE_MID;
+            new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
+
+            irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
+            irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
+            irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
+            irv.btn          = new_node;
+            return irv;
+          } else {
+            irv.btn = NULL;
+            return irv;
+          }
+        }
       } else {                                        /* search to the left */
-       index -= inc;
-       if ((inc = inc >> 1) == 0) {
-         inc = 1;
-       }
+        index -= inc;
+        if ((inc = inc >> 1) == 0) {
+          inc = 1;
+        }
       }
 
     } else {                                          /* look to the right */
 
       if ((index == node->num_blocks - 1) || 
-         (startslot < node->blocks[index+1].startslot)) {
-       if (node->child[index+1] != NULL) {           /* take right child */
-         irv = btree_insert_int(ss, node->child[index+1], startslot, nslots);
-         if (irv.btn == NULL) {
-           return irv;
-         } else {                                    /* merge return value */
-           int i, j;                                 /*   insert on right  */
-           for (i = node->num_blocks; i > index + 1; i--) {
-             node->blocks[i].startslot     = node->blocks[i-1].startslot;
-             node->blocks[i].nslots        = node->blocks[i-1].nslots;
-             node->blocks[i].listblock     = node->blocks[i-1].listblock;
-             node->blocks[i].listblock->sb = &(node->blocks[i]);
-             node->child[i+1]              = node->child[i];
-           }
-           node->blocks[index+1].startslot     = irv.sb.startslot;
-           node->blocks[index+1].nslots        = irv.sb.nslots;
-           node->blocks[index+1].listblock     = irv.sb.listblock;
-           node->blocks[index+1].listblock->sb = &(node->blocks[index+1]);
-           node->child[index+2]                = irv.btn;
-           node->num_blocks++;
-           if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
-             btreenode *new_node = create_btree_node();
-             for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
-               j = i - (TREE_NODE_MID + 1);
-               new_node->blocks[j].startslot     = node->blocks[i].startslot;
-               new_node->blocks[j].nslots        = node->blocks[i].nslots;
-               new_node->blocks[j].listblock     = node->blocks[i].listblock;
-               new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
-             }
-             for (i = TREE_NODE_MID + 1; i <= TREE_NODE_SIZE; i++) {
-               new_node->child[i-(TREE_NODE_MID+1)] = node->child[i];
-             }
-             node->num_blocks     = TREE_NODE_MID;
-             new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
-
-             irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
-             irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
-             irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
-             irv.btn          = new_node;
-             return irv;
-           } else {
-             irv.btn = NULL;
-             return irv;
-           }
-         }
-       } else {                                      /* insert to the right */
-         int i, j;
-         for (i = node->num_blocks; i > index + 1; i--) {
-           node->blocks[i].startslot     = node->blocks[i-1].startslot;
-           node->blocks[i].nslots        = node->blocks[i-1].nslots;
-           node->blocks[i].listblock     = node->blocks[i-1].listblock;
-           node->blocks[i].listblock->sb = &(node->blocks[i]);
-         }
-         node->blocks[index+1].startslot = startslot;
-         node->blocks[index+1].nslots    = nslots;
-         node->blocks[index+1].listblock = list_insert(ss, &(node->blocks[index+1]));
-         node->num_blocks++;
-         if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
-           btreenode *new_node = create_btree_node();
-           for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
-             j = i - (TREE_NODE_MID + 1);
-             new_node->blocks[j].startslot     = node->blocks[i].startslot;
-             new_node->blocks[j].nslots        = node->blocks[i].nslots;
-             new_node->blocks[j].listblock     = node->blocks[i].listblock;
-             new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
-           }
-           node->num_blocks = TREE_NODE_MID;
-           new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
-
-           irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
-           irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
-           irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
-           irv.btn          = new_node;
-           return irv;
-         } else {
-           irv.btn = NULL;
-           return irv;
-         }
-       }
+          (startslot < node->blocks[index+1].startslot)) {
+        if (node->child[index+1] != NULL) {           /* take right child */
+          irv = btree_insert_int(ss, node->child[index+1], startslot, nslots);
+          if (irv.btn == NULL) {
+            return irv;
+          } else {                                    /* merge return value */
+            int i, j;                                 /*   insert on right  */
+            for (i = node->num_blocks; i > index + 1; i--) {
+              node->blocks[i].startslot     = node->blocks[i-1].startslot;
+              node->blocks[i].nslots        = node->blocks[i-1].nslots;
+              node->blocks[i].listblock     = node->blocks[i-1].listblock;
+              node->blocks[i].listblock->sb = &(node->blocks[i]);
+              node->child[i+1]              = node->child[i];
+            }
+            node->blocks[index+1].startslot     = irv.sb.startslot;
+            node->blocks[index+1].nslots        = irv.sb.nslots;
+            node->blocks[index+1].listblock     = irv.sb.listblock;
+            node->blocks[index+1].listblock->sb = &(node->blocks[index+1]);
+            node->child[index+2]                = irv.btn;
+            node->num_blocks++;
+            if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
+              btreenode *new_node = create_btree_node();
+              for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
+                j = i - (TREE_NODE_MID + 1);
+                new_node->blocks[j].startslot     = node->blocks[i].startslot;
+                new_node->blocks[j].nslots        = node->blocks[i].nslots;
+                new_node->blocks[j].listblock     = node->blocks[i].listblock;
+                new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
+              }
+              for (i = TREE_NODE_MID + 1; i <= TREE_NODE_SIZE; i++) {
+                new_node->child[i-(TREE_NODE_MID+1)] = node->child[i];
+              }
+              node->num_blocks     = TREE_NODE_MID;
+              new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
+
+              irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
+              irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
+              irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
+              irv.btn          = new_node;
+              return irv;
+            } else {
+              irv.btn = NULL;
+              return irv;
+            }
+          }
+        } else {                                      /* insert to the right */
+          int i, j;
+          for (i = node->num_blocks; i > index + 1; i--) {
+            node->blocks[i].startslot     = node->blocks[i-1].startslot;
+            node->blocks[i].nslots        = node->blocks[i-1].nslots;
+            node->blocks[i].listblock     = node->blocks[i-1].listblock;
+            node->blocks[i].listblock->sb = &(node->blocks[i]);
+          }
+          node->blocks[index+1].startslot = startslot;
+          node->blocks[index+1].nslots    = nslots;
+          node->blocks[index+1].listblock = list_insert(ss, &(node->blocks[index+1]));
+          node->num_blocks++;
+          if (node->num_blocks == TREE_NODE_SIZE) {   /* split node */
+            btreenode *new_node = create_btree_node();
+            for (i = TREE_NODE_MID + 1; i < TREE_NODE_SIZE; i++) {
+              j = i - (TREE_NODE_MID + 1);
+              new_node->blocks[j].startslot     = node->blocks[i].startslot;
+              new_node->blocks[j].nslots        = node->blocks[i].nslots;
+              new_node->blocks[j].listblock     = node->blocks[i].listblock;
+              new_node->blocks[j].listblock->sb = &(new_node->blocks[j]);
+            }
+            node->num_blocks = TREE_NODE_MID;
+            new_node->num_blocks = TREE_NODE_SIZE - TREE_NODE_MID - 1;
+
+            irv.sb.startslot = node->blocks[TREE_NODE_MID].startslot;
+            irv.sb.nslots    = node->blocks[TREE_NODE_MID].nslots;
+            irv.sb.listblock = node->blocks[TREE_NODE_MID].listblock;
+            irv.btn          = new_node;
+            return irv;
+          } else {
+            irv.btn = NULL;
+            return irv;
+          }
+        }
       } else {                                        /* search to the right */
-       index += inc;
-       if ((inc = inc >> 1) == 0) {
-         inc = 1;
-       }
+        index += inc;
+        if ((inc = inc >> 1) == 0) {
+          inc = 1;
+        }
       }
     }
   }
@@ -597,7 +620,7 @@ static insert_ret_val btree_insert_int(slotset *ss, btreenode *node,
 }
 
 static btreenode *btree_insert(slotset *ss, btreenode *node, 
-                              CmiInt8 startslot, CmiInt8 nslots) {
+    CmiInt8 startslot, CmiInt8 nslots) {
 
   /* check the b-tree root: if it's empty, insert the element in the
      first position */
@@ -637,10 +660,11 @@ static btreenode *btree_insert(slotset *ss, btreenode *node,
  *****************************************************************/
 
 static void btree_delete_int(slotset *ss, btreenode *node, 
-                            CmiInt8 startslot, slotblock *sb) {
+    CmiInt8 startslot, slotblock *sb) {
 
-  int index, inc;
-  int i;
+  int i, index, inc;
+  int def_child;
+  int num_left, num_right, left_pos, right_pos;
 
   /* If sb is not NULL, we're sending sb down the tree to a leaf to be
      swapped with the next larger startslot so it can be deleted from
@@ -667,10 +691,10 @@ static void btree_delete_int(slotset *ss, btreenode *node,
 
       /* delete the slotblock */
       for (i = 0; i < (node->num_blocks - 1); i++) {
-       node->blocks[i].startslot     = node->blocks[i+1].startslot;
-       node->blocks[i].nslots        = node->blocks[i+1].nslots;
-       node->blocks[i].listblock     = node->blocks[i+1].listblock;
-       node->blocks[i].listblock->sb = &(node->blocks[i]);
+        node->blocks[i].startslot     = node->blocks[i+1].startslot;
+        node->blocks[i].nslots        = node->blocks[i+1].nslots;
+        node->blocks[i].listblock     = node->blocks[i+1].listblock;
+        node->blocks[i].listblock->sb = &(node->blocks[i]);
       }
       node->num_blocks--;
 
@@ -690,60 +714,57 @@ static void btree_delete_int(slotset *ss, btreenode *node,
     while (1) {
 
       if (startslot == node->blocks[index].startslot) {   /* found it */
-       if (node->child[index+1] != NULL) {               /* not a leaf */
-         btree_delete_int(ss, node->child[index+1], 
-                          startslot, &(node->blocks[index]));
-         break;
-       } else {                                          /* is a leaf */
-         int i;
-         /* delete the slotblock */
-         list_delete(ss, &(node->blocks[index]));
-         for (i = index; i < (node->num_blocks - 1); i++) {
-           node->blocks[i].startslot     = node->blocks[i+1].startslot;
-           node->blocks[i].nslots        = node->blocks[i+1].nslots;
-           node->blocks[i].listblock     = node->blocks[i+1].listblock;
-           node->blocks[i].listblock->sb = &(node->blocks[i]);
-         }
-         node->num_blocks--;
-         return;
-       }
+        if (node->child[index+1] != NULL) {               /* not a leaf */
+          btree_delete_int(ss, node->child[index+1], 
+              startslot, &(node->blocks[index]));
+          break;
+        } else {                                          /* is a leaf */
+          /* delete the slotblock */
+          list_delete(ss, &(node->blocks[index]));
+          for (i = index; i < (node->num_blocks - 1); i++) {
+            node->blocks[i].startslot     = node->blocks[i+1].startslot;
+            node->blocks[i].nslots        = node->blocks[i+1].nslots;
+            node->blocks[i].listblock     = node->blocks[i+1].listblock;
+            node->blocks[i].listblock->sb = &(node->blocks[i]);
+          }
+          node->num_blocks--;
+          return;
+        }
       } else {
-       if (startslot < node->blocks[index].startslot) {  /* look left */
-         if ((index == 0) ||                             /* take left child */
-             (startslot > node->blocks[index-1].startslot)) {
-           btree_delete_int(ss, node->child[index], startslot, sb);
-           break;
-         } else {                                        /* search left */
-           index -= inc;
-           if ((inc = inc >> 1) == 0) {
-             inc = 1;
-           }
-         }
-       } else {                                          /* look right */
-         if ((index == node->num_blocks - 1) ||          /* take right child */
-             (startslot < node->blocks[index+1].startslot)) {
-           btree_delete_int(ss, node->child[index+1], startslot, sb);
-           break;
-         } else {                                        /* search right */
-           index += inc;
-           if ((inc = inc >> 1) == 0) {
-             inc = 1;
-           }
-         }
-       }
+        if (startslot < node->blocks[index].startslot) {  /* look left */
+          if ((index == 0) ||                             /* take left child */
+              (startslot > node->blocks[index-1].startslot)) {
+            btree_delete_int(ss, node->child[index], startslot, sb);
+            break;
+          } else {                                        /* search left */
+            index -= inc;
+            if ((inc = inc >> 1) == 0) {
+              inc = 1;
+            }
+          }
+        } else {                                          /* look right */
+          if ((index == node->num_blocks - 1) ||          /* take right child */
+              (startslot < node->blocks[index+1].startslot)) {
+            btree_delete_int(ss, node->child[index+1], startslot, sb);
+            break;
+          } else {                                        /* search right */
+            index += inc;
+            if ((inc = inc >> 1) == 0) {
+              inc = 1;
+            }
+          }
+        }
       }
 
     }
 
   }
 
-  {   /* BLOCK
-     At this point, the desired slotblock has been removed, and we're
+  /* At this point, the desired slotblock has been removed, and we're
      going back up the tree.  We must check for deficient nodes that
      require the rotating or combining of elements to maintain a
      balanced b-tree. */
-  int i;
-  int def_child = -1;
+  def_child = -1;
 
   /* check if one of the child nodes is deficient  */
   if (node->child[index]->num_blocks < TREE_NODE_MID) {
@@ -757,51 +778,51 @@ static void btree_delete_int(slotset *ss, btreenode *node,
     /* if there is a left sibling and it has enough elements, rotate */
     /* to the right */
     if ((def_child != 0) && (node->child[def_child-1] != NULL) && 
-       (node->child[def_child-1]->num_blocks > TREE_NODE_MID)) {
+        (node->child[def_child-1]->num_blocks > TREE_NODE_MID)) {
 
       /* move all elements in deficient child to the right */
       for (i = node->child[def_child]->num_blocks; i > 0; i--) {
-       node->child[def_child]->blocks[i].startslot = 
-         node->child[def_child]->blocks[i-1].startslot;
-       node->child[def_child]->blocks[i].nslots = 
-         node->child[def_child]->blocks[i-1].nslots;
-       node->child[def_child]->blocks[i].listblock = 
-         node->child[def_child]->blocks[i-1].listblock;
-       node->child[def_child]->blocks[i].listblock->sb = 
-         &(node->child[def_child]->blocks[i]);
+        node->child[def_child]->blocks[i].startslot = 
+          node->child[def_child]->blocks[i-1].startslot;
+        node->child[def_child]->blocks[i].nslots = 
+          node->child[def_child]->blocks[i-1].nslots;
+        node->child[def_child]->blocks[i].listblock = 
+          node->child[def_child]->blocks[i-1].listblock;
+        node->child[def_child]->blocks[i].listblock->sb = 
+          &(node->child[def_child]->blocks[i]);
       }
       for (i = node->child[def_child]->num_blocks + 1; i > 0; i--) {
-       node->child[def_child]->child[i] = 
-         node->child[def_child]->child[i-1];
+        node->child[def_child]->child[i] = 
+          node->child[def_child]->child[i-1];
       }
 
       /* move parent element to the deficient child */
       node->child[def_child]->blocks[0].startslot = 
-       node->blocks[def_child-1].startslot;
+        node->blocks[def_child-1].startslot;
       node->child[def_child]->blocks[0].nslots = 
-       node->blocks[def_child-1].nslots;
+        node->blocks[def_child-1].nslots;
       node->child[def_child]->blocks[0].listblock = 
-       node->blocks[def_child-1].listblock;
+        node->blocks[def_child-1].listblock;
       node->child[def_child]->blocks[0].listblock->sb = 
-       &(node->child[def_child]->blocks[0]);
+        &(node->child[def_child]->blocks[0]);
       node->child[def_child]->num_blocks++;
 
       /* move the right-most child of the parent's left child to the
          left-most child of the formerly deficient child  */
       i = node->child[def_child-1]->num_blocks;
       node->child[def_child]->child[0] = 
-       node->child[def_child-1]->child[i];
+        node->child[def_child-1]->child[i];
 
       /* move largest element from left child up to the parent */
       i--;
       node->blocks[def_child-1].startslot = 
-       node->child[def_child-1]->blocks[i].startslot;
+        node->child[def_child-1]->blocks[i].startslot;
       node->blocks[def_child-1].nslots = 
-       node->child[def_child-1]->blocks[i].nslots;
+        node->child[def_child-1]->blocks[i].nslots;
       node->blocks[def_child-1].listblock = 
-       node->child[def_child-1]->blocks[i].listblock;
+        node->child[def_child-1]->blocks[i].listblock;
       node->blocks[def_child-1].listblock->sb = 
-       &(node->blocks[def_child-1]);
+        &(node->blocks[def_child-1]);
       node->child[def_child-1]->num_blocks--;
 
     }
@@ -809,54 +830,53 @@ static void btree_delete_int(slotset *ss, btreenode *node,
     /* otherwise, if there is a right sibling and it has enough */
     /* elements, rotate to the left */
     else if (((def_child + 1) <= node->num_blocks) && 
-            (node->child[def_child+1] != NULL) && 
-            (node->child[def_child+1]->num_blocks > TREE_NODE_MID)) {
+        (node->child[def_child+1] != NULL) && 
+        (node->child[def_child+1]->num_blocks > TREE_NODE_MID)) {
 
       /* move parent element to the deficient child */
       i = node->child[def_child]->num_blocks;
       node->child[def_child]->blocks[i].startslot = 
-       node->blocks[def_child].startslot;
+        node->blocks[def_child].startslot;
       node->child[def_child]->blocks[i].nslots = 
-       node->blocks[def_child].nslots;
+        node->blocks[def_child].nslots;
       node->child[def_child]->blocks[i].listblock = 
-       node->blocks[def_child].listblock;
+        node->blocks[def_child].listblock;
       node->child[def_child]->blocks[i].listblock->sb = 
-       &(node->child[def_child]->blocks[i]);
+        &(node->child[def_child]->blocks[i]);
       node->child[def_child]->num_blocks++;
 
       /* move the left-most child of the parent's right child to the
          right-most child of the formerly deficient child  */
       i++;
       node->child[def_child]->child[i] = 
-       node->child[def_child+1]->child[0];
+        node->child[def_child+1]->child[0];
 
       /* move smallest element from right child up to the parent */
       node->blocks[def_child].startslot = 
-       node->child[def_child+1]->blocks[0].startslot;
+        node->child[def_child+1]->blocks[0].startslot;
       node->blocks[def_child].nslots = 
-       node->child[def_child+1]->blocks[0].nslots;
+        node->child[def_child+1]->blocks[0].nslots;
       node->blocks[def_child].listblock = 
-       node->child[def_child+1]->blocks[0].listblock;
+        node->child[def_child+1]->blocks[0].listblock;
       node->blocks[def_child].listblock->sb = 
-       &(node->blocks[def_child]);
+        &(node->blocks[def_child]);
       node->child[def_child+1]->num_blocks--;
 
       /* move all elements in the parent's right child to the left  */
       for (i = 0; i < node->child[def_child+1]->num_blocks; i++) {
-       node->child[def_child+1]->blocks[i].startslot = 
-         node->child[def_child+1]->blocks[i+1].startslot;
-       node->child[def_child+1]->blocks[i].nslots = 
-         node->child[def_child+1]->blocks[i+1].nslots;
-       node->child[def_child+1]->blocks[i].listblock = 
-         node->child[def_child+1]->blocks[i+1].listblock;
-       node->child[def_child+1]->blocks[i].listblock->sb = 
-         &(node->child[def_child+1]->blocks[i]);
+        node->child[def_child+1]->blocks[i].startslot = 
+          node->child[def_child+1]->blocks[i+1].startslot;
+        node->child[def_child+1]->blocks[i].nslots = 
+          node->child[def_child+1]->blocks[i+1].nslots;
+        node->child[def_child+1]->blocks[i].listblock = 
+          node->child[def_child+1]->blocks[i+1].listblock;
+        node->child[def_child+1]->blocks[i].listblock->sb = 
+          &(node->child[def_child+1]->blocks[i]);
       }
       for (i = 0; i < node->child[def_child+1]->num_blocks + 1; i++) {
-       node->child[def_child+1]->child[i] = 
-         node->child[def_child+1]->child[i+1];
+        node->child[def_child+1]->child[i] = 
+          node->child[def_child+1]->child[i+1];
       }
-    }    /* BLOCK */
     }
 
     /* otherwise, merge the deficient node, parent, and the parent's
@@ -867,38 +887,37 @@ static void btree_delete_int(slotset *ss, btreenode *node,
       /* move the parent element into the left child node */
       i = node->child[index]->num_blocks;
       node->child[index]->blocks[i].startslot = 
-       node->blocks[index].startslot;
+        node->blocks[index].startslot;
       node->child[index]->blocks[i].nslots = 
-       node->blocks[index].nslots;
+        node->blocks[index].nslots;
       node->child[index]->blocks[i].listblock = 
-       node->blocks[index].listblock;
+        node->blocks[index].listblock;
       node->child[index]->blocks[i].listblock->sb = 
-       &(node->child[index]->blocks[i]);
+        &(node->child[index]->blocks[i]);
       node->child[index]->num_blocks++;
 
-      {   /* BLOCK */
       /* move the elements and children of the right child node to the */
       /* left child node */
-      int num_left  = node->child[index]->num_blocks;
-      int num_right = node->child[index+1]->num_blocks;
-      int left_pos;
-      int right_pos = 0;
+      num_left  = node->child[index]->num_blocks;
+      num_right = node->child[index+1]->num_blocks;
+      left_pos;
+      right_pos = 0;
       for (left_pos = num_left; left_pos < num_left + num_right; left_pos++) {
-       node->child[index]->blocks[left_pos].startslot = 
-         node->child[index+1]->blocks[right_pos].startslot;
-       node->child[index]->blocks[left_pos].nslots = 
-         node->child[index+1]->blocks[right_pos].nslots;
-       node->child[index]->blocks[left_pos].listblock = 
-         node->child[index+1]->blocks[right_pos].listblock;
-       node->child[index]->blocks[left_pos].listblock->sb = 
-         &(node->child[index]->blocks[left_pos]);
-       right_pos++;
+        node->child[index]->blocks[left_pos].startslot = 
+          node->child[index+1]->blocks[right_pos].startslot;
+        node->child[index]->blocks[left_pos].nslots = 
+          node->child[index+1]->blocks[right_pos].nslots;
+        node->child[index]->blocks[left_pos].listblock = 
+          node->child[index+1]->blocks[right_pos].listblock;
+        node->child[index]->blocks[left_pos].listblock->sb = 
+          &(node->child[index]->blocks[left_pos]);
+        right_pos++;
       }
       right_pos = 0;
       for (left_pos = num_left; left_pos < num_left + num_right + 1; left_pos++) {
-       node->child[index]->child[left_pos] = 
-         node->child[index+1]->child[right_pos];
-       right_pos++;
+        node->child[index]->child[left_pos] = 
+          node->child[index+1]->child[right_pos];
+        right_pos++;
       }
       node->child[index]->num_blocks = num_left + num_right;
 
@@ -909,13 +928,13 @@ static void btree_delete_int(slotset *ss, btreenode *node,
       /* update the parent node */
       node->num_blocks--;
       for (i = index; i < node->num_blocks; i++) {
-       node->blocks[i].startslot     = node->blocks[i+1].startslot;
-       node->blocks[i].nslots        = node->blocks[i+1].nslots;
-       node->blocks[i].listblock     = node->blocks[i+1].listblock;
-       node->blocks[i].listblock->sb = &(node->blocks[i]);
-       node->child[i+1]              = node->child[i+2];
+        node->blocks[i].startslot     = node->blocks[i+1].startslot;
+        node->blocks[i].nslots        = node->blocks[i+1].nslots;
+        node->blocks[i].listblock     = node->blocks[i+1].listblock;
+        node->blocks[i].listblock->sb = &(node->blocks[i]);
+        node->child[i+1]              = node->child[i+2];
       }
-      }  /* BLOCK */
+
     }
 
   }
@@ -999,7 +1018,7 @@ static CmiInt8 get_slots(slotset *ss, CmiInt8 nslots) {
     dlln = ss->list_array[i];
     while (dlln != NULL) {
       if (dlln->sb->nslots >= nslots) {
-       return dlln->sb->startslot;
+        return dlln->sb->startslot;
       }
       dlln = dlln->next;
     }
@@ -1026,20 +1045,20 @@ static void grab_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots) {
   if (sb == NULL) {
     CmiAbort("requested a non-existent slotblock\n");
   } else {
-    
+
     if (sb->startslot == sslot) {
 
       /* range is exact range of slotblock - delete block from tree */
       if (sb->nslots == nslots) {
-       ss->btree_root = btree_delete(ss, ss->btree_root, sslot);
+        ss->btree_root = btree_delete(ss, ss->btree_root, sslot);
       }
 
       /* range is at beginning of slotblock - update block range */
       else {
-       CmiInt8 old_nslots = sb->nslots;
-       sb->startslot     += nslots;
-       sb->nslots        -= nslots;
-       list_move(ss, sb->listblock, old_nslots);
+        CmiInt8 old_nslots = sb->nslots;
+        sb->startslot     += nslots;
+        sb->nslots        -= nslots;
+        list_move(ss, sb->listblock, old_nslots);
       }
 
     } else {
@@ -1047,19 +1066,19 @@ static void grab_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots) {
       /* range is at end of slotblock - update block range */
       endslot = sb->startslot + sb->nslots - 1;
       if (endslot == (sslot + nslots - 1)) {
-       CmiInt8 old_nslots = sb->nslots;
-       sb->nslots        -= nslots;
-       list_move(ss, sb->listblock, old_nslots);
+        CmiInt8 old_nslots = sb->nslots;
+        sb->nslots        -= nslots;
+        list_move(ss, sb->listblock, old_nslots);
       }
 
       /* range is in middle of slotblock - update block range with the */
       /* new lower range and insert a block with the new upper range */
       else {
-       CmiInt8 old_nslots = sb->nslots;
-       sb->nslots         = sslot - sb->startslot;
-       list_move(ss, sb->listblock, old_nslots);
-       ss->btree_root = btree_insert(ss, ss->btree_root, sslot + nslots, 
-                                     endslot - (sslot + nslots) + 1);
+        CmiInt8 old_nslots = sb->nslots;
+        sb->nslots         = sslot - sb->startslot;
+        list_move(ss, sb->listblock, old_nslots);
+        ss->btree_root = btree_insert(ss, ss->btree_root, sslot + nslots, 
+            endslot - (sslot + nslots) + 1);
       }
 
     }
@@ -1146,11 +1165,11 @@ static void delete_list_array(slotset *ss) {
     dlln = ss->list_array[i];
     if (dlln != NULL) {
       while (dlln->next != NULL) {
-       dlln = dlln->next;
+        dlln = dlln->next;
       }
       while (dlln->previous != NULL) {
-       dlln = dlln->previous;
-       free_reentrant(dlln->next);
+        dlln = dlln->previous;
+        free_reentrant(dlln->next);
       }
       free_reentrant(dlln);
     }
@@ -1190,13 +1209,13 @@ static int print_btree_level(btreenode *node, int level, int current_level, int
     if (current_level == level) {
       print_btree_node(node, node_num);
       if (node->child[0] == NULL) {
-       return 0;
+        return 0;
       } else {
-       return 1;
+        return 1;
       }
     } else {
       another_level = print_btree_level(node->child[i], level, 
-                                       current_level + 1, i);
+          current_level + 1, i);
     }
   }
   return another_level;
@@ -1228,9 +1247,9 @@ static void print_list_array(slotset *ss) {
     dlln = ss->list_array[i];
     while (dlln != NULL) {
       if (dlln->previous != NULL) {
-       CmiPrintf("<->");
+        CmiPrintf("<->");
       } else {
-       CmiPrintf(" ->");
+        CmiPrintf(" ->");
       }
       CmiPrintf("[%lld,%lld]", dlln->sb->startslot, dlln->sb->nslots);
       dlln = dlln->next;
@@ -1239,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);
@@ -1274,7 +1293,7 @@ typedef struct _slotset
  * empty slots. The slot numbers are [startslot,startslot+nslot-1]
  */
 
-static slotset *
+  static slotset *
 new_slotset(CmiInt8 startslot, CmiInt8 nslots)
 {
   /* CmiPrintf("*** Old isomalloc ***\n"); */
@@ -1296,7 +1315,7 @@ new_slotset(CmiInt8 startslot, CmiInt8 nslots)
  * returns new block of empty slots. if it cannot find any, returns (-1).
  */
 
-static CmiInt8
+  static CmiInt8
 get_slots(slotset *ss, CmiInt8 nslots)
 {
   /* CmiPrintf("old get: nslots=%lld\n", nslots); */
@@ -1311,7 +1330,7 @@ get_slots(slotset *ss, CmiInt8 nslots)
 
 /* just adds a slotblock to an empty position in the given slotset. */
 
-static void
+  static void
 add_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
 {
   int pos; 
@@ -1349,7 +1368,7 @@ add_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
  * this is different from get_slots, since it pre-specifies the
  * slots to be grabbed.
  */
-static void
+  static void
 grab_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
 {
   /* CmiPrintf("old grab: sslot=%lld nslots=%lld\n", sslot, nslots); */
@@ -1380,7 +1399,7 @@ grab_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
  * if it cannot find such a slotblock, it creates a new slotblock.
  * If the buffer fills up, it adds up extra buffer space.
  */
-static void
+  static void
 free_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
 {
   /* CmiPrintf("old free: sslot=%lld nslots=%lld\n", sslot, nslots); */
@@ -1395,18 +1414,18 @@ free_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
     /* e is the ending slot of pos'th slotblock */
     if (e == sslot) /* append to the current slotblock */
     {
-           ss->buf[pos].nslots += nslots;
-           ss->emptyslots += nslots;
-           /* CmiPrintf("free:append pos=%d\n", pos); */
-           return;
+      ss->buf[pos].nslots += nslots;
+      ss->emptyslots += nslots;
+      /* CmiPrintf("free:append pos=%d\n", pos); */
+      return;
     }
     if(eslot == ss->buf[pos].startslot) /* prepend to the current slotblock */
     {
-           ss->buf[pos].startslot = sslot;
-           ss->buf[pos].nslots += nslots;
-           ss->emptyslots += nslots;
-           /* CmiPrintf("free:prepend pos=%d\n", pos); */
-           return;
+      ss->buf[pos].startslot = sslot;
+      ss->buf[pos].nslots += nslots;
+      ss->emptyslots += nslots;
+      /* CmiPrintf("free:prepend pos=%d\n", pos); */
+      return;
     }
   }
   /* if we are here, it means we could not find a slotblock that the */
@@ -1417,16 +1436,16 @@ free_slots(slotset *ss, CmiInt8 sslot, CmiInt8 nslots)
 
 /*
  * destroys slotset-- currently unused
-static void
-delete_slotset(slotset* ss)
-{
 free_reentrant(ss->buf);
 free_reentrant(ss);
-}
-*/
+ static void
+ delete_slotset(slotset* ss)
+ {
+ free_reentrant(ss->buf);
+ free_reentrant(ss);
+ }
+ */
 
-#if CMK_THREADS_DEBUG
-static void
+#if ISOMALLOC_DEBUG
+  static void
 print_slots(slotset *ss)
 {
   int i;
@@ -1440,7 +1459,7 @@ print_slots(slotset *ss)
 }
 #else
 /*#  define print_slots(ss) */ /*empty*/
-static void
+  static void
 print_slots(slotset *ss)
 {
   int i;
@@ -1462,46 +1481,46 @@ print_slots(slotset *ss)
 
 
 /*This version of the allocate/deallocate calls are used if the 
-real mmap versions are disabled.*/
+  real mmap versions are disabled.*/
 static int disabled_map_warned=0;
 static void *disabled_map(int nBytes) 
 {
-       if (!disabled_map_warned) {
-               disabled_map_warned=1;
-               if (CmiMyPe()==0)
-                       CmiError("charm isomalloc.c> Warning: since mmap() doesn't work,"
-                       " you won't be able to migrate threads\n");
-       }
-       return malloc(nBytes);
+  if (!disabled_map_warned) {
+    disabled_map_warned=1;
+    if (CmiMyPe()==0)
+      CmiError("charm isomalloc.c> Warning: since mmap() doesn't work,"
+          " you won't be able to migrate threads\n");
+  }
+  return malloc(nBytes);
 }
 static void disabled_unmap(void *bk) {
-       free(bk);
+  free(bk);
 }
 
 /*Turn off isomalloc memory, for the given reason*/
 static void disable_isomalloc(const char *why)
 {
-    isomallocStart=NULL;
-    isomallocEnd=NULL;
-    if (CmiMyPe() == 0)
+  isomallocStart=NULL;
+  isomallocEnd=NULL;
+  if (CmiMyPe() == 0)
     CmiPrintf("[%d] isomalloc.c> Disabling isomalloc because %s\n",CmiMyPe(),why);
 }
 
 #if ! CMK_HAS_MMAP
 /****************** Manipulate memory map (Win32 non-version) *****************/
 static void *call_mmap_fixed(void *addr,size_t len) {
-       CmiAbort("isomalloc.c: mmap_fixed should never be called here.");
-       return NULL;
+  CmiAbort("isomalloc.c: mmap_fixed should never be called here.");
+  return NULL;
 }
 static void *call_mmap_anywhere(size_t len) {
-       CmiAbort("isomalloc.c: mmap_anywhere should never be called here.");
-       return NULL;
+  CmiAbort("isomalloc.c: mmap_anywhere should never be called here.");
+  return NULL;
 }
 static void call_munmap(void *addr,size_t len) {
-       CmiAbort("isomalloc.c: munmap should never be called here.");
+  CmiAbort("isomalloc.c: munmap should never be called here.");
 }
 
-static int 
+  static int 
 init_map(char **argv)
 {
   return 0; /*Isomalloc never works without mmap*/
@@ -1523,19 +1542,19 @@ CpvStaticDeclare(int, zerofd); /*File descriptor for /dev/zero, for mmap*/
 static void *call_mmap(void *addr,size_t len, int flags) {
   void *ret=mmap(addr, len, PROT_READ|PROT_WRITE,
 #if CMK_HAS_MMAP_ANON
-           flags|MAP_PRIVATE|MAP_ANON,-1,
+      flags|MAP_PRIVATE|MAP_ANON,-1,
 #else
-           flags|MAP_PRIVATE,CpvAccess(zerofd),
+      flags|MAP_PRIVATE,CpvAccess(zerofd),
 #endif
-           0);
+      0);
   if (ret==((void*)(-1))) return (void *)0; /* all-ones means failure */
   else return ret;
 }
 static void *call_mmap_fixed(void *addr,size_t len) {
-       return call_mmap(addr,len,MAP_FIXED);
+  return call_mmap(addr,len,MAP_FIXED);
 }
 static void *call_mmap_anywhere(size_t len) {
-       return call_mmap((void *)0,len,0);
+  return call_mmap((void *)0,len,0);
 }
 
 /* Unmaps this address range */
@@ -1547,7 +1566,7 @@ static void call_munmap(void *addr,size_t len) {
     CmiAbort("munmap call failed to deallocate requested memory.\n");
 }
 
-static int 
+  static int 
 init_map(char **argv)
 {
 #if CMK_HAS_MMAP_ANON
@@ -1563,20 +1582,19 @@ init_map(char **argv)
 
 #endif /* UNIX memory map */
 
-
 /**
  * maps the virtual memory associated with slot using mmap
  */
-static CmiIsomallocBlock *
+  static CmiIsomallocBlock *
 map_slots(CmiInt8 slot, CmiInt8 nslots)
 {
   void *pa;
   void *addr=slot2addr(slot);
   pa = call_mmap_fixed(addr, slotsize*nslots);
-  
-  if (pa==NULL) 
+
+  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
@@ -1584,15 +1602,15 @@ 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);
+      slot,slot+nslots-1,addr);
 #endif
   return (CmiIsomallocBlock *)pa;
 }
@@ -1600,22 +1618,22 @@ map_slots(CmiInt8 slot, CmiInt8 nslots)
 /*
  * unmaps the virtual memory associated with slot using munmap
  */
-static void
+  static void
 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);
+      slot,slot+nslots-1,addr);
 #endif
 }
 
 static void map_failed(CmiInt8 s,CmiInt8 n)
 {
   void *addr=slot2addr(s);
-  CmiError("charm isomalloc.c> map failed to allocate %d bytes at %p.\n",
-      slotsize*n, addr);
+  CmiError("charm isomalloc.c> map failed to allocate %d bytes at %p, errno:%d.\n",
+      slotsize*n, addr, errno);
   CmiAbort("Exiting\n");
 }
 
@@ -1625,6 +1643,44 @@ static void map_failed(CmiInt8 s,CmiInt8 n)
 
 CpvStaticDeclare(slotset *, myss); /*My managed slots*/
 
+#if CMK_USE_MEMPOOL_ISOMALLOC
+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)
+{
+  CmiInt8 s,n,i;
+  void *newaddr;
+  n=length2slots(*size);
+  /*Always satisfy mallocs with local slots:*/
+  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);
+    CmiAbort("Out of virtual address space for isomalloc");
+  }
+  grab_slots(CpvAccess(myss),s,n);
+  for (i=0; i<5; i++) {
+    newaddr=map_slots(s,n);
+    if (newaddr!=NULL) break;
+#if CMK_HAS_USLEEP
+    if (errno == ENOMEM) { usleep(rand()%1000); continue; }
+    else break;
+#endif
+  }
+  if (!newaddr) map_failed(s,n);
+  *((CmiInt8 *)mem_hndl) = s;
+  *size = n*slotsize;
+  return newaddr;
+}
+
+//free function to be used by mempool
+void isofreefn(void *ptr, mem_handle_t mem_hndl)
+{
+  call_munmap(ptr, ((block_header *)ptr)->size);
+}
+#endif
+
 /*This struct describes a range of virtual addresses*/
 typedef struct {
   char *start; /*First byte of region*/
@@ -1648,12 +1704,12 @@ static void *__static_data_loc(void)
 
 /*Pointer comparison is in these subroutines, because
   comparing arbitrary pointers is nonportable and tricky.
-*/
+  */
 static int pointer_lt(const char *a,const char *b) {
-       return ((memRange_t)a)<((memRange_t)b);
+  return ((memRange_t)a)<((memRange_t)b);
 }
 static int pointer_ge(const char *a,const char *b) {
-       return ((memRange_t)a)>=((memRange_t)b);
+  return ((memRange_t)a)>=((memRange_t)b);
 }
 
 static char *pmin(char *a,char *b) {return pointer_lt(a,b)?a:b;}
@@ -1664,12 +1720,12 @@ const static memRange_t gig=1024u*1024u*1024u; /*One gigabyte*/
 
 /*Check if this memory location is usable.  
   If not, return 1.
-*/
+  */
 static int bad_location(char *loc) {
   void *addr;
   addr=call_mmap_fixed(loc,slotsize);
-  if (addr==NULL) {
-#if CMK_THREADS_DEBUG
+  if (addr==NULL || addr!=loc) {
+#if ISOMALLOC_DEBUG
     CmiPrintf("[%d] Skipping unmappable space at %p\n",CmiMyPe(),loc);
 #endif
     return 1; /*No good*/
@@ -1680,13 +1736,14 @@ static int bad_location(char *loc) {
 
 /* Split this range up into n pieces, returning the size of each piece */
 static memRange_t divide_range(memRange_t len,int n) {
-       return (len+1)/n;
+  return (len+1)/n;
 }
 
 /* Return if this memory region has *any* good parts. */
 static int partially_good(char *start,memRange_t len,int n) {
   int i;
   memRange_t quant=divide_range(len,n);
+  CmiAssert (quant > 0);
   for (i=0;i<n;i++)
     if (!bad_location(start+i*quant)) return 1; /* it's got some good parts */
   return 0; /* all locations are bad */
@@ -1697,6 +1754,11 @@ 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 ISOMALLOC_DEBUG
+  CmiPrintf("good_range: %lld, %d\n", quant, n);
+#endif
+  CmiAssert (quant > 0);
+
   for (i=0;i<n;i++)
     if (bad_location(start+i*quant)) return 0; /* it's got some bad parts */
   /* It's all good: */
@@ -1705,23 +1767,22 @@ static int good_range(char *start,memRange_t len,int n) {
 
 /*Check if this entire memory range, or some subset 
   of the range, is usable.  If so, write it into max.
-*/
+  */
 static void check_range(char *start,char *end,memRegion_t *max)
 {
   memRange_t len;
-  char *initialStart=start, *initialEnd=end;
   CmiUInt8 tb = (CmiUInt8)gig*1024ul;   /* One terabyte */
   CmiUInt8 vm_limit = tb*256ul;   /* terabyte */
 
   if (start>=end) return; /*Ran out of hole*/
   len=(memRange_t)end-(memRange_t)start;
-  
+
 #if 0
-    /* too conservative */
+  /* too conservative */
   if (len/gig>64u) { /* This is an absurd amount of space-- cut it down, for safety */
-     start+=16u*gig;
-     end=start+32u*gig;
-     len=(memRange_t)end-(memRange_t)start;  
+    start+=16u*gig;
+    end=start+32u*gig;
+    len=(memRange_t)end-(memRange_t)start;  
   }
 #else
   /* Note: 256TB == 248 bytes.  So a 48-bit virtual-address CPU 
@@ -1734,28 +1795,28 @@ 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
-  
+
   /* Check the middle of the range */
   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);
     for (i=0;i<n;i++) {
-        char *cur=start+i*len;
-       if (partially_good(cur,len,16))
-          check_range(cur,cur+len,max);
+      char *cur=start+i*len;
+      if (partially_good(cur,len,16))
+        check_range(cur,cur+len,max);
     }
     return; /* Hopefully one of the subranges will be any good */
   }
   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
 
@@ -1768,7 +1829,7 @@ static void check_range(char *start,char *end,memRegion_t *max)
 
 /*Find the first available memory region of at least the
   given size not touching any data in the used list.
- */
 */
 static memRegion_t find_free_region(memRegion_t *used,int nUsed,int atLeast) 
 {
   memRegion_t max;
@@ -1781,7 +1842,7 @@ static memRegion_t find_free_region(memRegion_t *used,int nUsed,int atLeast)
     /*Consider a hole starting at the end of region i*/
     char *holeStart=used[i].start+used[i].len;
     char *holeEnd=(void *)(-1);
-    
+
     /*Shrink the hole by all others*/ 
     for (j=0;j<nUsed && pointer_lt(holeStart,holeEnd);j++) {
       if (pointer_lt(used[j].start,holeStart)) 
@@ -1797,88 +1858,92 @@ static memRegion_t find_free_region(memRegion_t *used,int nUsed,int atLeast)
 }
 
 /*
-By looking at the address range carefully, try to find 
-the largest usable free region on the machine.
-*/
+   By looking at the address range carefully, try to find 
+   the largest usable free region on the machine.
+   */
 static int find_largest_free_region(memRegion_t *destRegion) {
-    char *staticData =(char *) __static_data_loc();
-    char *code = (char *)&find_free_region;
-    char *threadData = (char *)&errno;
-    char *codeDll = (char *)fprintf;
-    char *heapLil = (char*) malloc(1);
-    char *heapBig = (char*) malloc(6*meg);
-    char *stack = (char *)__cur_stack_frame();
-    size_t mmapAnyLen = 1*meg;
-    char *mmapAny = (char*) call_mmap_anywhere(mmapAnyLen);
-
-    int i,nRegions=9;
-    memRegion_t regions[10]; /*used portions of address space*/
-    memRegion_t freeRegion; /*Largest unused block of address space*/
-
-/*Mark off regions of virtual address space as ususable*/
-    regions[0].type="NULL";
-    regions[0].start=NULL; regions[0].len=16u*meg;
-    
-    regions[1].type="Static program data";
-    regions[1].start=staticData; regions[1].len=256u*meg;
-    
-    regions[2].type="Program executable code";
-    regions[2].start=code; regions[2].len=256u*meg;
-    
-    regions[3].type="Heap (small blocks)";
-    regions[3].start=heapLil; regions[3].len=1u*gig;
-    
-    regions[4].type="Heap (large blocks)";
-    regions[4].start=heapBig; regions[4].len=1u*gig;
-    
-    regions[5].type="Stack space";
-    regions[5].start=stack; regions[5].len=256u*meg;
-
-    regions[6].type="Program dynamically linked code";
-    regions[6].start=codeDll; regions[6].len=256u*meg; 
-
-    regions[7].type="Result of a non-fixed call to mmap";
-    regions[7].start=mmapAny; regions[7].len=1u*gig; 
-
-    regions[8].type="Thread private data";
-    regions[8].start=threadData; regions[8].len=256u*meg; 
-
-    _MEMCHECK(heapBig); free(heapBig);
-    _MEMCHECK(heapLil); free(heapLil); 
-    call_munmap(mmapAny,mmapAnyLen);
-    
-    /*Align each memory region*/
-    for (i=0;i<nRegions;i++) {
-      memRegion_t old=regions[i];
-      memRange_t p=(memRange_t)regions[i].start;
-      p&=~(regions[i].len-1); /*Round start down to a len-boundary (mask off low bits)*/
-      regions[i].start=(char *)p;
+  char *staticData =(char *) __static_data_loc();
+  char *code = (char *)&find_free_region;
+  char *threadData = (char *)&errno;
+  char *codeDll = (char *)fprintf;
+  char *heapLil = (char*) malloc(1);
+  char *heapBig = (char*) malloc(6*meg);
+  char *stack = (char *)__cur_stack_frame();
+  size_t mmapAnyLen = 1*meg;
+  char *mmapAny = (char*) call_mmap_anywhere(mmapAnyLen);
+
+  int i,nRegions=0;
+  memRegion_t regions[10]; /*used portions of address space*/
+  memRegion_t freeRegion; /*Largest unused block of address space*/
+
+  /*Mark off regions of virtual address space as ususable*/
+  regions[nRegions].type="NULL";
+  regions[nRegions].start=NULL; 
+#if CMK_POWER7 && CMK_64BIT
+  regions[nRegions++].len=2u*gig;   /* on bluedrop, don't mess with the lower memory region */
+#else
+  regions[nRegions++].len=16u*meg;
+#endif
+
+  regions[nRegions].type="Static program data";
+  regions[nRegions].start=staticData; regions[nRegions++].len=256u*meg;
+
+  regions[nRegions].type="Program executable code";
+  regions[nRegions].start=code; regions[nRegions++].len=256u*meg;
+
+  regions[nRegions].type="Heap (small blocks)";
+  regions[nRegions].start=heapLil; regions[nRegions++].len=1u*gig;
+
+  regions[nRegions].type="Heap (large blocks)";
+  regions[nRegions].start=heapBig; regions[nRegions++].len=1u*gig;
+
+  regions[nRegions].type="Stack space";
+  regions[nRegions].start=stack; regions[nRegions++].len=256u*meg;
+
+  regions[nRegions].type="Program dynamically linked code";
+  regions[nRegions].start=codeDll; regions[nRegions++].len=256u*meg; 
+
+  regions[nRegions].type="Result of a non-fixed call to mmap";
+  regions[nRegions].start=mmapAny; regions[nRegions++].len=2u*gig; 
+
+  regions[nRegions].type="Thread private data";
+  regions[nRegions].start=threadData; regions[nRegions++].len=256u*meg; 
+
+  _MEMCHECK(heapBig); free(heapBig);
+  _MEMCHECK(heapLil); free(heapLil); 
+  call_munmap(mmapAny,mmapAnyLen);
+
+  /*Align each memory region*/
+  for (i=0;i<nRegions;i++) {
+    memRegion_t old=regions[i];
+    memRange_t p=(memRange_t)regions[i].start;
+    p&=~(regions[i].len-1); /*Round start down to a len-boundary (mask off low bits)*/
+    regions[i].start=(char *)p;
 #if CMK_MACOSX
-      if (regions[i].start+regions[i].len*2>regions[i].start) regions[i].len *= 2;
+    if (regions[i].start+regions[i].len*2>regions[i].start) regions[i].len *= 2;
 #endif
-#if CMK_THREADS_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);
+#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);
 #endif
-    }
-    
-    /*Find a large, unused region in this map: */
-    freeRegion=find_free_region(regions,nRegions,(512u)*meg);
-    
-    if (freeRegion.start==0) 
-    { /*No free address space-- disable isomalloc:*/
-      return 0;
-    }
-    else /* freeRegion is valid */
-    {
-      *destRegion=freeRegion;
-      
-      return 1;
-    }
+  }
+
+  /*Find a large, unused region in this map: */
+  freeRegion=find_free_region(regions,nRegions,(512u)*meg);
+
+  if (freeRegion.start==0) 
+  { /*No free address space-- disable isomalloc:*/
+    return 0;
+  }
+  else /* freeRegion is valid */
+  {
+    *destRegion=freeRegion;
+
+    return 1;
+  }
 }
 
-#if CMK_MMAP_PROBE
 static int try_largest_mmap_region(memRegion_t *destRegion)
 {
   void *bad_alloc=(void*)(-1); /* mmap error return address */
@@ -1886,47 +1951,61 @@ static int try_largest_mmap_region(memRegion_t *destRegion)
   double shrink = 1.5;
   static int count = 0;
   size_t size=((size_t)(-1l)), good_size=0;
-  if (sizeof(size_t) > 8) size = size>>2;  /* 25% of machine address space! */
+  int retry = 0;
+  if (sizeof(size_t) >= 8) size = size>>2;  /* 25% of machine address space! */
   while (1) { /* test out an allocation of this size */
-       range=mmap(NULL,size,PROT_READ|PROT_WRITE,
-                    MAP_PRIVATE
+#if CMK_HAS_MMAP
+    range=mmap(NULL,size,PROT_READ|PROT_WRITE,
+        MAP_PRIVATE
 #if CMK_HAS_MMAP_ANON
-                    |MAP_ANON
+        |MAP_ANON
 #endif
 #if CMK_HAS_MMAP_NORESERVE
-                     |MAP_NORESERVE
-#endif
-                     ,-1,0);
-       if (range==bad_alloc) { /* mmap failed */
-               size=(double)size/shrink; /* shrink request */
-               if (size<=0) return 0; /* mmap doesn't work */
-       }
-       else { /* this allocation size is available */
-               munmap(range,size); /* needed/wanted? */
-               if (size > good_size) {
-                 good_range = range;
-                 good_size = size;
-                 size=((double)size)*1.1;
-                 continue;
-               }
-               break;
-       }
+        |MAP_NORESERVE
+#endif
+        ,-1,0);
+#else
+    range = bad_alloc;
+#endif
+    if (range == bad_alloc) {  /* mmap failed */
+#if ISOMALLOC_DEBUG
+      /* CmiPrintf("[%d] test failed at size: %llu error: %d\n", CmiMyPe(), size, errno);  */
+#endif
+#if CMK_HAS_USLEEP
+      if (retry++ < 5) { usleep(rand()%10000); continue; }
+      else retry = 0;
+#endif
+      size=(double)size/shrink; /* shrink request */
+      if (size<=0) return 0; /* mmap doesn't work */
+    }
+    else { /* this allocation size is available */
+#if ISOMALLOC_DEBUG
+      CmiPrintf("[%d] available: %p, %lld\n", CmiMyPe(), range, size);
+#endif
+      call_munmap(range,size); /* needed/wanted? */
+      if (size > good_size) {
+        good_range = range;
+        good_size = size;
+        size=((double)size)*1.1;
+        continue;
+      }
+      break;
+    }
   }
   CmiAssert(good_range!=NULL);
   destRegion->start=good_range; 
   destRegion->len=good_size;
-#if CMK_THREADS_DEBUG
-pid_t pid = getpid();
-{
-char s[128];
-sprintf(s, "cat /proc/%d/maps", pid);
-system(s);
-}
+#if ISOMALLOC_DEBUG
+  pid_t pid = getpid();
+  {
+    char s[128];
+    sprintf(s, "cat /proc/%d/maps", pid);
+    system(s);
+  }
   CmiPrintf("[%d] try_largest_mmap_region: %p, %lld\n", CmiMyPe(), good_range, good_size);
 #endif
   return 1;
 }
-#endif
 
 #ifndef CMK_CPV_IS_SMP
 #define CMK_CPV_IS_SMP
@@ -1937,165 +2016,236 @@ static void init_ranges(char **argv)
   memRegion_t freeRegion;
   /*Largest value a signed int can hold*/
   memRange_t intMax=(((memRange_t)1)<<(sizeof(int)*8-1))-1;
+  int pagesize = 0;
 
   /*Round slot size up to nearest page size*/
+#if CMK_USE_MEMPOOL_ISOMALLOC
+  slotsize=1024*1024;
+#else
   slotsize=16*1024;
-  slotsize=(slotsize+CMK_MEMORY_PAGESIZE-1) & ~(CMK_MEMORY_PAGESIZE-1);
-#if CMK_THREADS_DEBUG
-  CmiPrintf("[%d] Using slotsize of %d\n", CmiMyPe(), slotsize);
+#endif 
+#if CMK_HAS_GETPAGESIZE
+  pagesize = getpagesize();
 #endif
+  if (pagesize < CMK_MEMORY_PAGESIZE)
+    pagesize = CMK_MEMORY_PAGESIZE;
+  slotsize=(slotsize+pagesize-1) & ~(pagesize-1);
 
+#if ISOMALLOC_DEBUG
+  if (CmiMyPe() == 0)
+    CmiPrintf("[%d] Using slotsize of %d\n", CmiMyPe(), slotsize);
+#endif
   freeRegion.len=0u;
 
   if (CmiMyRank()==0 && numslots==0)
   { /* Find the largest unused region of virtual address space */
 #ifdef CMK_MMAP_START_ADDRESS /* Hardcoded start address, for machines where automatic fails */
-      freeRegion.start=CMK_MMAP_START_ADDRESS;
-      freeRegion.len=CMK_MMAP_LENGTH_MEGS*meg;
+    freeRegion.start=CMK_MMAP_START_ADDRESS;
+    freeRegion.len=CMK_MMAP_LENGTH_MEGS*meg;
 #endif
-#if CMK_MMAP_PROBE
-      if (freeRegion.len==0u) 
+
+    if (freeRegion.len==0u)  {
+      if (_mmap_probe == 1) {
         if (try_largest_mmap_region(&freeRegion)) _sync_iso = 1;
-#else
-      if (freeRegion.len==0u) find_largest_free_region(&freeRegion);
-#endif
-      
+      }
+      else {
+        if (freeRegion.len==0u) find_largest_free_region(&freeRegion);
+      }
+    }
+
 #if 0
-      /*Make sure our largest slot number doesn't overflow an int:*/
-      if (freeRegion.len/slotsize>intMax)
-        freeRegion.len=intMax*slotsize;
+    /*Make sure our largest slot number doesn't overflow an int:*/
+    if (freeRegion.len/slotsize>intMax)
+      freeRegion.len=intMax*slotsize;
 #endif
-      
-      if (freeRegion.len==0u) {
-        disable_isomalloc("no free virtual address space");
-      }
-      else /* freeRegion.len>0, so can isomalloc */
-      {
-#if CMK_THREADS_DEBUG
-        CmiPrintf("[%d] Isomalloc memory region: %p - %p (%d megs)\n",CmiMyPe(),
-             freeRegion.start,freeRegion.start+freeRegion.len,
-             freeRegion.len/meg);
+
+    if (freeRegion.len==0u) {
+      disable_isomalloc("no free virtual address space");
+    }
+    else /* freeRegion.len>0, so can isomalloc */
+    {
+#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
-       intersect of all memory regions on all nodes.
-    */
+  /*
+     on some machines, isomalloc memory regions on different nodes 
+     can be different. use +isomalloc_sync to calculate the
+     intersect of all memory regions on all nodes.
+     */
   if (_sync_iso == 1)
   {
-        if (CmiMyRank() == 0 && freeRegion.len > 0u) {
-          if (CmiBarrier() == -1 && CmiMyPe()==0) 
-            CmiAbort("Charm++ Error> +isomalloc_sync requires CmiBarrier() implemented.\n");
-          else {
-            CmiUInt8 s = (CmiUInt8)freeRegion.start;
-            CmiUInt8 e = (CmiUInt8)(freeRegion.start+freeRegion.len);
-            int fd, i;
-            char fname[128];
+#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
+      {
+        CmiUInt8 s = (CmiUInt8)freeRegion.start;
+        CmiUInt8 e = (CmiUInt8)(freeRegion.start+freeRegion.len);
+        int fd, i,j;
+        char fname[128];
 
-            if (CmiMyNode()==0) printf("Charm++> synchronizing isomalloc memory region...\n");
+        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);
+        /* remove file before writing for safe */
+        unlink(fname);
 #if CMK_HAS_SYNC && ! CMK_DISABLE_SYNC
-            system("sync");
+        system("sync");
 #endif
 
-            CmiBarrier();
+        CmiBarrier();
 
-              /* write region into file */
-            while ((fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0644)) == -1) 
+        /* write region into file */
+        while ((fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0644)) == -1) 
 #ifndef __MINGW_H
-              CMK_CPV_IS_SMP
+          CMK_CPV_IS_SMP
 #endif
             ;
-            write(fd, &s, sizeof(CmiUInt8));
-            write(fd, &e, sizeof(CmiUInt8));
-            close(fd);
+        write(fd, &s, sizeof(CmiUInt8));
+        write(fd, &e, sizeof(CmiUInt8));
+        close(fd);
 
 #if CMK_HAS_SYNC && ! CMK_DISABLE_SYNC
-            system("sync");
+        system("sync");
 #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++;
+        CmiBarrier();
+        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));
-              close(fd);
-              if (ss>s) s = ss;
-              if (ee<e) e = 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;
+          }
+        }
 
-            CmiBarrier();
+        CmiBarrier();
 
-            unlink(fname);
+        unlink(fname);
 #if CMK_HAS_SYNC && ! CMK_DISABLE_SYNC
-            system("sync");
+        system("sync");
 #endif
 
-              /* update */
-            if (s > e)  {
-              CmiAbort("isomalloc> failed to find consolidated isomalloc region!");
-            }
-            freeRegion.start = (void *)s;
-            freeRegion.len = (char *)e -(char *)s;
-
-            if (CmiMyPe() == 0)
-            CmiPrintf("[%d] consolidated Isomalloc memory region: %p - %p (%d megs)\n",CmiMyPe(),
-             freeRegion.start,freeRegion.start+freeRegion.len,
-             freeRegion.len/meg);
-          }   /* end of barrier test */
-        } /* end of rank 0 */
-        else {
-          CmiBarrier();
-          CmiBarrier();
-          CmiBarrier();
-          CmiBarrier();
+        /* update */
+        if (s > e)  {
+          if (CmiMyPe()==0) CmiPrintf("[%d] Invalid isomalloc region: %lx - %lx.\n", CmiMyPe(), s, e);
+          CmiAbort("isomalloc> failed to find consolidated isomalloc region!");
         }
+        freeRegion.start = (void *)s;
+        freeRegion.len = (char *)e -(char *)s;
+
+        if (CmiMyPe() == 0)
+          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 {
+      CmiBarrier();
+      CmiBarrier();
+      CmiBarrier();
+      CmiBarrier();
+    }
   }
 
+#ifdef __FAULT__
+AFTER_SYNC:
+#endif
+
   if (CmiMyRank() == 0 && freeRegion.len > 0u)
   {
-        /*Isomalloc covers entire unused region*/
-        isomallocStart=freeRegion.start;
-        isomallocEnd=freeRegion.start+freeRegion.len;
-        numslots=(freeRegion.len/slotsize)/CmiNumPes();
-        
-#if CMK_THREADS_DEBUG
-        CmiPrintf("[%d] Can isomalloc up to %lu megs per pe\n",CmiMyPe(),
-             ((memRange_t)numslots)*slotsize/meg);
+    /*Isomalloc covers entire unused region*/
+    isomallocStart=freeRegion.start;
+    isomallocEnd=freeRegion.start+freeRegion.len;
+    numslots=(freeRegion.len/slotsize)/CmiNumPes();
+
+#if ISOMALLOC_DEBUG
+    CmiPrintf("[%d] Can isomalloc up to %lu megs per pe\n",CmiMyPe(),
+        ((memRange_t)numslots)*slotsize/meg);
 #endif
   }
 
   /*SMP Mode: wait here for rank 0 to initialize numslots before calculating myss*/
   CmiNodeAllBarrier(); 
-  
+
+  CpvInitialize(slotset *, myss);
+  CpvAccess(myss) = NULL;
+
+#if CMK_USE_MEMPOOL_ISOMALLOC
+  CtvInitialize(mempool_type *, threadpool);
+  CtvAccess(threadpool) = NULL;
+#endif
+
   if (isomallocStart!=NULL) {
-    CpvInitialize(slotset *, myss);
     CpvAccess(myss) = new_slotset(pe2slot(CmiMyPe()), numslots);
   }
 }
@@ -2112,141 +2262,175 @@ typedef struct _slotmsg
 
 static slotmsg *prepare_slotmsg(CmiInt8 slot,CmiInt8 nslots)
 {
-       slotmsg *m=(slotmsg *)CmiAlloc(sizeof(slotmsg));
-       m->pe=CmiMyPe();
-       m->slot=slot;
-       m->nslots=nslots;
-       return m;
+  slotmsg *m=(slotmsg *)CmiAlloc(sizeof(slotmsg));
+  m->pe=CmiMyPe();
+  m->slot=slot;
+  m->nslots=nslots;
+  return m;
 }
 
 static void grab_remote(slotmsg *msg)
 {
-       grab_slots(CpvAccess(myss),msg->slot,msg->nslots);
-       CmiFree(msg);
+  grab_slots(CpvAccess(myss),msg->slot,msg->nslots);
+  CmiFree(msg);
 }
 
 static void free_remote(slotmsg *msg)
 {
-       free_slots(CpvAccess(myss),msg->slot,msg->nslots);
-       CmiFree(msg);
+  free_slots(CpvAccess(myss),msg->slot,msg->nslots);
+  CmiFree(msg);
 }
 static int grab_remote_idx, free_remote_idx;
 
 struct slotOP {
-       /*Function pointer to perform local operation*/
-       void (*local)(slotset *ss,CmiInt8 s,CmiInt8 n);
-       /*Index to perform remote operation*/
-       int remote;
+  /*Function pointer to perform local operation*/
+  void (*local)(slotset *ss,CmiInt8 s,CmiInt8 n);
+  /*Index to perform remote operation*/
+  int remote;
 };
 typedef struct slotOP slotOP;
 static slotOP grabOP,freeOP;
 
 static void init_comm(char **argv)
 {
-       grab_remote_idx=CmiRegisterHandler((CmiHandler)grab_remote);
-       free_remote_idx=CmiRegisterHandler((CmiHandler)free_remote);    
-       grabOP.local=grab_slots;
-       grabOP.remote=grab_remote_idx;
-       freeOP.local=free_slots;
-       freeOP.remote=free_remote_idx;  
+  grab_remote_idx=CmiRegisterHandler((CmiHandler)grab_remote);
+  free_remote_idx=CmiRegisterHandler((CmiHandler)free_remote); 
+  grabOP.local=grab_slots;
+  grabOP.remote=grab_remote_idx;
+  freeOP.local=free_slots;
+  freeOP.remote=free_remote_idx;       
 }
 
 /*Apply the given operation to the given slots which
   lie on the given processor.*/
 static void one_slotOP(const slotOP *op,int pe,CmiInt8 s,CmiInt8 n)
 {
-/*Shrink range to only those covered by this processor*/
-       /*First and last slot for this processor*/
-       CmiInt8 p_s=pe2slot(pe), p_e=pe2slot(pe+1);
-       CmiInt8 e=s+n;
-       if (s<p_s) s=p_s;
-       if (e>p_e) e=p_e;
-       n=e-s;
-
-/*Send off range*/
-       if (pe==CmiMyPe()) 
-               op->local(CpvAccess(myss),s,n);
-       else 
-       {/*Remote request*/
-               slotmsg *m=prepare_slotmsg(s,n);
-               CmiSetHandler(m, freeOP.remote);
-               CmiSyncSendAndFree(pe,sizeof(slotmsg),m);
-       }
+  /*Shrink range to only those covered by this processor*/
+  /*First and last slot for this processor*/
+  CmiInt8 p_s=pe2slot(pe), p_e=pe2slot(pe+1);
+  CmiInt8 e=s+n;
+  if (s<p_s) s=p_s;
+  if (e>p_e) e=p_e;
+  n=e-s;
+
+  /*Send off range*/
+  if (pe==CmiMyPe()) 
+    op->local(CpvAccess(myss),s,n);
+  else 
+  {/*Remote request*/
+    slotmsg *m=prepare_slotmsg(s,n);
+    CmiSetHandler(m, freeOP.remote);
+    CmiSyncSendAndFree(pe,sizeof(slotmsg),m);
+  }
 }
 
 /*Apply the given operation to all slots in the range [s, s+n) 
-After a restart from checkpoint, a slotset can cross an 
-arbitrary set of processors.
-*/
+  After a restart from checkpoint, a slotset can cross an 
+  arbitrary set of processors.
+  */
 static void all_slotOP(const slotOP *op,CmiInt8 s,CmiInt8 n)
 {
-       int spe=slot2pe(s), epe=slot2pe(s+n-1);
-       int pe;
-       for (pe=spe; pe<=epe; pe++)
-               one_slotOP(op,pe,s,n);
+  int spe=slot2pe(s), epe=slot2pe(s+n-1);
+  int pe;
+  for (pe=spe; pe<=epe; pe++)
+    one_slotOP(op,pe,s,n);
 }
 
 /************** External interface ***************/
-void *CmiIsomalloc(int size)
+#if CMK_USE_MEMPOOL_ISOMALLOC
+void *CmiIsomalloc(int size, CthThread tid)
 {
-       CmiInt8 s,n;
-       CmiIsomallocBlock *blk;
-       if (isomallocStart==NULL) return disabled_map(size);
-       n=length2slots(size);
-       /*Always satisfy mallocs with local slots:*/
-       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);
-               CmiAbort("Out of virtual address space for isomalloc");
-       }
-       grab_slots(CpvAccess(myss),s,n);
-       blk=map_slots(s,n);
-       if (!blk) map_failed(s,n);
-       blk->slot=s;
-       blk->length=size;
-       return block2pointer(blk);
+  CmiInt8 s,n,i;
+  CmiIsomallocBlock *blk;
+  if (isomallocStart==NULL) return disabled_map(size);
+  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->slot=(CmiInt8)blk;
+  blk->length=size;
+  return block2pointer(blk);
+}
+#else
+void *CmiIsomalloc(int size, CthThread tid)
+{
+  CmiInt8 s,n,i;
+  CmiIsomallocBlock *blk;
+  if (isomallocStart==NULL) return disabled_map(size);
+  n=length2slots(size);
+  /*Always satisfy mallocs with local slots:*/
+  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);
+    CmiAbort("Out of virtual address space for isomalloc");
+  }
+  grab_slots(CpvAccess(myss),s,n);
+  for (i=0; i<5; i++) {
+    blk=map_slots(s,n);
+    if (blk!=NULL) break;
+#if CMK_HAS_USLEEP
+    if (errno == ENOMEM) { usleep(rand()%1000); continue; }
+    else break;
+#endif
+  }
+  if (!blk) map_failed(s,n);
+  blk->slot=s;
+  blk->length=size;
+  return block2pointer(blk);
 }
+#endif
 
 #define MALLOC_ALIGNMENT           (2*sizeof(size_t))
 #define MINSIZE                    (sizeof(CmiIsomallocBlock))
 
 /** return an aligned isomalloc memory, the alignment occurs after the
- *  first 'reserved' bytes
+ *  first 'reserved' bytes.  Total requested size is (size+reserved)
  */
-static void *_isomallocAlign(size_t align, size_t size, size_t reserved)
-{
-        void *ptr;
-        intptr_t ptr2align;
-        CmiInt8 s, n, slot;
-
-        if (align < MINSIZE) align = MINSIZE;
-        /* make sure alignment is power of 2 */
-        if ((align & (align - 1)) != 0) {
-          size_t a = MALLOC_ALIGNMENT * 2;
-          while ((unsigned long)a < (unsigned long)align) a <<= 1;
-          align = a;
-        }
-        /* s = size + align + reserved; */
-        s = size + align;
-        ptr = CmiIsomalloc(s);
-        ptr2align = (intptr_t)ptr;
-        ptr2align += reserved;
-        if (ptr2align % align != 0) { /* misaligned */
-          CmiIsomallocBlock *blk = pointer2block(ptr);  /* save block */
-          CmiIsomallocBlock savedblk = *blk;
-          ptr2align = (ptr2align + align - 1) & -((CmiInt8) align);
-          ptr2align -= reserved;
-          ptr = (void*)ptr2align;
-          blk = pointer2block(ptr);      /* restore block */
-          *blk = savedblk;
-        }
-       return ptr;
+static void *_isomallocAlign(size_t align, size_t size, size_t reserved, CthThread t) {
+  void *ptr;
+  CmiIntPtr ptr2align;
+  CmiInt8 s;
+
+  if (align < MINSIZE) align = MINSIZE;
+  /* make sure alignment is power of 2 */
+  if ((align & (align - 1)) != 0) {
+    size_t a = MALLOC_ALIGNMENT * 2;
+    while ((unsigned long)a < (unsigned long)align) a <<= 1;
+    align = a;
+  }
+  s = size + reserved + align;
+  ptr = CmiIsomalloc(s,t);
+  ptr2align = (CmiIntPtr)ptr;
+  ptr2align += reserved;
+  if (ptr2align % align != 0) { /* misaligned */
+    CmiIsomallocBlock *blk = pointer2block(ptr);  /* save block */
+    CmiIsomallocBlock savedblk = *blk;
+    ptr2align = (ptr2align + align - 1) & -((CmiInt8) align);
+    ptr2align -= reserved;
+    ptr = (void*)ptr2align;
+    blk = pointer2block(ptr);      /* restore block */
+    *blk = savedblk;
+  }
+  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()
@@ -2256,71 +2440,79 @@ int CmiIsomallocEnabled()
 
 void CmiIsomallocPup(pup_er p,void **blockPtrPtr)
 {
-       CmiIsomallocBlock *blk;
-       CmiInt8 s,length;
-        CmiInt8 n;
-       if (isomallocStart==NULL) CmiAbort("isomalloc is disabled-- cannot use IsomallocPup");
-
-       if (!pup_isUnpacking(p)) 
-       { /*We have an existing block-- unpack start slot & length*/
-               blk=pointer2block(*blockPtrPtr);
-               s=blk->slot;
-               length=blk->length;
-       }
-       
-       pup_int8(p,&s);
-       pup_int8(p,&length);
-       n=length2slots(length);
-       
-       if (pup_isUnpacking(p)) 
-       { /*Must allocate a new block in its old location*/
-               if (pup_isUserlevel(p) || pup_isRestarting(p))
-                       /*Checkpoint: must grab old slots (even remote!)*/
-                       all_slotOP(&grabOP,s,n);
-               blk=map_slots(s,n);
-               if (!blk) map_failed(s,n);
-               blk->slot=s;
-               blk->length=length;
-               *blockPtrPtr=block2pointer(blk);
-       }
-       
-       /*Pup the allocated data*/
-       pup_bytes(p,*blockPtrPtr,length);
-       
-       if (pup_isDeleting(p)) 
-       { /*Unmap old slots, but do not mark as free*/
-               unmap_slots(s,n);
-               *blockPtrPtr=NULL; /*Zero out user's pointer*/
-       }
+  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)) 
+  { /*We have an existing block-- unpack start slot & length*/
+    blk=pointer2block(*blockPtrPtr);
+    s=blk->slot;
+    length=blk->length;
+  }
+
+  pup_int8(p,&s);
+  pup_int8(p,&length);
+  n=length2slots(length);
+
+  if (pup_isUnpacking(p)) 
+  { /*Must allocate a new block in its old location*/
+    if (pup_isUserlevel(p) || pup_isRestarting(p))
+    {  /*Checkpoint: must grab old slots (even remote!)*/
+      all_slotOP(&grabOP,s,n);
+    }
+    blk=map_slots(s,n);
+    if (!blk) map_failed(s,n);
+    blk->slot=s;
+    blk->length=length;
+    *blockPtrPtr=block2pointer(blk);
+  }
+
+  /*Pup the allocated data*/
+  pup_bytes(p,*blockPtrPtr,length);
+
+  if (pup_isDeleting(p)) 
+  { /*Unmap old slots, but do not mark as free*/
+    unmap_slots(s,n);
+    *blockPtrPtr=NULL; /*Zero out user's pointer*/
+  }
 }
 
 void CmiIsomallocFree(void *blockPtr)
 {
-       if (isomallocStart==NULL) {
-               disabled_unmap(blockPtr);
-       }
-       else if (blockPtr!=NULL)
-       {
-               CmiIsomallocBlock *blk=pointer2block(blockPtr);
-               CmiInt8 s=blk->slot; 
-                CmiInt8 n=length2slots(blk->length);
-               unmap_slots(s,n);
-               /*Mark used slots as free*/
-               all_slotOP(&freeOP,s,n);
-       }
-}
-
-CmiInt8   CmiIsomallocLength(void *block)
+  if (isomallocStart==NULL) {
+    disabled_unmap(blockPtr);
+  }
+  else if (blockPtr!=NULL)
+  {
+#if CMK_USE_MEMPOOL_ISOMALLOC
+    mempool_free_thread((void*)pointer2block(blockPtr)->slot);
+#else
+    CmiIsomallocBlock *blk=pointer2block(blockPtr);
+    CmiInt8 s=blk->slot; 
+    CmiInt8 n=length2slots(blk->length);
+    unmap_slots(s,n);
+    /*Mark used slots as free*/
+    all_slotOP(&freeOP,s,n);
+#endif
+  }
+}
+
+CmiInt8  CmiIsomallocLength(void *block)
 {
-       return pointer2block(block)->length;
+  return pointer2block(block)->length;
 }
 
 /*Return true if this address is in the region managed by isomalloc*/
 int CmiIsomallocInRange(void *addr)
 {
-       if (isomallocStart==NULL) return 0; /* There is no range we manage! */
-       return pointer_ge((char *)addr,isomallocStart) && 
-              pointer_lt((char*)addr,isomallocEnd);
+  if (isomallocStart==NULL) return 0; /* There is no range we manage! */
+  return pointer_ge((char *)addr,isomallocStart) && 
+    pointer_lt((char*)addr,isomallocEnd);
 }
 
 void CmiIsomallocInit(char **argv)
@@ -2328,15 +2520,33 @@ void CmiIsomallocInit(char **argv)
 #if CMK_NO_ISO_MALLOC
   disable_isomalloc("isomalloc disabled by conv-mach");
 #else
+  if (CmiGetArgFlagDesc(argv,"+noisomalloc","disable isomalloc")) {
+    disable_isomalloc("isomalloc disabled by user.");
+    return;
+  }
+#if CMK_MMAP_PROBE
+  _mmap_probe = 1;
+#elif CMK_MMAP_TEST
+  _mmap_probe = 0;
+#endif
+  if (CmiGetArgFlagDesc(argv,"+isomalloc_probe","call mmap to probe the largest available isomalloc region"))
+    _mmap_probe = 1;
+  if (CmiGetArgFlagDesc(argv,"+isomalloc_test","mmap test common areas for the largest available isomalloc region"))
+    _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");
   }
   else {
-    if (read_randomflag() == 1) {    /* randomization stack pointer */
-      if (CmiMyPe() == 0) {
+    if (CmiMyPe() == 0) {
+      if (read_randomflag() == 1) {    /* randomization stack pointer */
         if (_sync_iso == 1)
           printf("Warning> Randomization of stack pointer is turned on in kernel.\n");
         else
@@ -2349,137 +2559,276 @@ void CmiIsomallocInit(char **argv)
 }
 
 /***************** BlockList interface *********
-This was moved here from memory-isomalloc.c when it 
-was realized that a list-of-isomalloc'd-blocks is useful for
-more than just isomalloc heaps.
-*/
-
-typedef CmiIsomallocBlockList Slot;
+  This was moved here from memory-isomalloc.c when it 
+  was realized that a list-of-isomalloc'd-blocks is useful for
+  more than just isomalloc heaps.
+  */
 
 /*Convert a slot to a user address*/
-static char *Slot_toUser(Slot *s) {return (char *)(s+1);}
-static Slot *Slot_fmUser(void *s) {return ((Slot *)s)-1;}
-
+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->next=ret; /*1-entry circular linked list*/
-       ret->prev=ret;
-       return ret;
+  CmiIsomallocBlockList *ret;
+  ret=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(*ret),tid);
+  ret->next=ret; /*1-entry circular linked list*/
+  ret->prev=ret;
+  return ret;
 }
 
-
 /* BIGSIM_OOC DEBUGGING */
 static void print_myslots();
 
 /*Pup all the blocks in this list.  This amounts to two circular
-list traversals.  Because everything's isomalloc'd, we don't even
-have to restore the pointers-- they'll be restored automatically!
-*/
-void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp)
+  list traversals.  Because everything's isomalloc'd, we don't even
+  have to restore the pointers-- they'll be restored automatically!
+  */
+#if CMK_USE_MEMPOOL_ISOMALLOC
+void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid)
 {
-        /* BIGSIM_OOC DEBUGGING */
-       /* if(!pup_isUnpacking(p)) print_myslots(); */
+  mempool_type *mptr;
+  block_header *current, *block_head;
+  slot_header *currSlot;
+  void *newblock;
+  CmiInt8 slot;
+  size_t size;
+  int flags[2];
+  int i, j;
+  int numBlocks = 0, numSlots = 0, flag = 1;
+
+#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) {
+      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++;
+    }
+  }
 
-       int i,nBlocks=0;
-       Slot *cur=NULL, *start=*lp;
+  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(CtvAccessOther(tid,threadpool));
+    *lp=NULL;
+  }
+  }
+#else
+  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;
 #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;
-               }
-               CmiIsomallocPup(p,&newBlock);
-               if (i==0 && pup_isUnpacking(p))
-                       *lp=(Slot *)newBlock;
-       }
-       if (pup_isDeleting(p))
-               *lp=NULL;
-
-       /* BIGSIM_OOC DEBUGGING */
-       /* if(pup_isUnpacking(p)) print_myslots(); */
-}
-
-/*Delete all the blocks in this list.*/
-void CmiIsomallocBlockListDelete(CmiIsomallocBlockList *l)
-{
-       Slot *start=l;
-       Slot *cur=start;
-       if (cur==NULL) return; /*Already deleted*/
-       do {
-               Slot *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)
-{
-       Slot *n; /*Newly created slot*/
-       n=(Slot *)CmiIsomalloc(sizeof(Slot)+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)
-{
-       Slot *n; /*Newly created slot*/
-       n=(Slot *)_isomallocAlign(align,sizeof(Slot)+nBytes,sizeof(Slot));
-       /*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)
-{
-       Slot *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 (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;
+      }
+      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(); */
+  }
 #endif
-       /*Link ourselves out of the blocklist*/
-       n->prev->next=n->next;
-       n->next->prev=n->prev;
-       CmiIsomallocFree(n);
-}
 
+  /*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);
+  }
 
-/* BIGSIM_OOC DEBUGGING */
-static void print_myslots(){
+  /*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");
+#endif
+    /*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));
-}
+  }