Merge branch 'charm' of charmgit:charm into isomalloc
authorNikhil Jain <nikhil@illinois.edu>
Tue, 11 Oct 2011 23:24:52 +0000 (18:24 -0500)
committerNikhil Jain <nikhil@illinois.edu>
Tue, 11 Oct 2011 23:24:52 +0000 (18:24 -0500)
Conflicts:
src/arch/util/mempool.c

1  2 
src/arch/util/mempool.c
src/arch/util/mempool.h
src/ck-core/cklocation.C
src/conv-core/converse.h
src/conv-core/global-elfcopy.C
src/conv-core/isomalloc.c
src/conv-core/mem-arena.c
src/conv-core/threads.c
src/libs/ck-libs/armci/armci_vp.C
src/libs/ck-libs/tcharm/tcharm.C
src/util/cmitls.c

index 64d3d4c4cc7798f5e7aa7a1dbb877486d51956e7,d493c86b48ca3fed13c2f66978aea3c785e6ec43..631825966f2765ac1d75a8e7cbc4c0c6b77da16f
@@@ -24,8 -24,7 +24,11 @@@ Generalized by Gengbin Zheng  10/5/201
  
  #include "mempool.h"
  
- //static      size_t     expand_mem = 1024*16;
- //static      size_t     expand_mem = 1024ll*1024*16;
++#if USE_MEMPOOL_ISOMALLOC
++static      size_t     expand_mem = 1024*16;
++#else
+ static      size_t     expand_mem = 1024ll*1024*16;
++#endif 
  
  mempool_type *mempool_init(size_t pool_size, mempool_newblockfn allocfn, mempool_freeblock freefn)
  {
      mptr->mempools_head.next = NULL;
      header = (mempool_header *) ((char*)pool+sizeof(mempool_type));
      mptr->freelist_head = sizeof(mempool_type);
- #if MEMPOOL_DEBUG
-     printf("[%d] pool: %p  free: %p\n", myrank, pool, header);
- #endif 
 -//printf("[%d] pool: %p  free: %p\n", myrank, pool, header);
      header->size = pool_size-sizeof(mempool_type)-sizeof(mempool_header);
      header->mem_hndl = mem_hndl;
      header->next_free = 0;
- #if 1 || MEMPOOL_DEBUG 
-     printf("[%d] Initiated mempool with %d memory at %p\n",CmiMyPe(),pool_size,pool);
++#if MEMPOOL_DEBUG 
++    printf("[%d] Initiated pool of size %lld at %p\n",CmiMyPe(),pool_size,mptr);
 +#endif
      return mptr;
  }
  
@@@ -64,7 -58,7 +64,6 @@@ void mempool_destroy(mempool_type *mptr
  
      while(mempools_head!= NULL)
      {
--        //printf("[%d] free mempool:%p\n", CmiMyPe(), mempools_head->mempool_ptr);
          current=mempools_head;
          mempools_head = mempools_head->next;
          freefn(current->mempool_ptr, current->mem_hndl);
@@@ -123,6 -119,6 +124,9 @@@ void*  mempool_malloc(mempool_type *mpt
  
      if(bestfit == NULL)
      {
++#if MEMPOOL_DEBUG 
++        printf("[%d] Expanding pool %p by %d\n",CmiMyPe(),mptr,CthSelf());
++#endif
          void *pool;
          mempool_block   *expand_pool;
          size_t   expand_size;
          expand_pool->mem_hndl = mem_hndl;
          expand_pool->size = expand_size;
          expand_pool->next = NULL;
- #if MEMPOOL_DEBUG
++#if  MEMPOOL_DEBUG
          printf("[%d] No memory has such free empty chunck of %d. expanding %p with new size %d\n", CmiMyPe(), size, expand_pool->mempool_ptr, expand_size);
 -          // FIXME: go to the end of link list
 +#endif
 +        // FIXME: go to the end of link list
          while (mempools_head->next != NULL) mempools_head = mempools_head->next;
          mempools_head->next = expand_pool;
  
index 94c689a6f91c62cb78f3ee0e87ac7c3c6d800c07,46c9aba7b66b731bc2f0ca066836a700da15e808..0614e3a0b463d0b3f4312330625f760a9e71acaa
@@@ -10,7 -10,7 +10,7 @@@
  #else
    // in uGNI, it is memory handler, other versions, this is an integer
    // a unique integer to represent the memory block
- typedef CmiInt8   gni_mem_handle_t;
 -typedef int    gni_mem_handle_t;
++typedef size_t   gni_mem_handle_t;
  #endif
  
  // multiple mempool for different size allocation
index 28ba03cb65d4f710f50c82c90853f4ea85c20f05,28ba03cb65d4f710f50c82c90853f4ea85c20f05..5917156bd44738b632b4b109119e6bf595fe439a
@@@ -2554,7 -2554,7 +2554,6 @@@ void CkLocMgr::emigrate(CkLocRec_local 
        if(!CmiNodeAlive(toPe)){
                return;
        }
--
        CkArrayIndex idx=rec->getIndex();
  
  #if CMK_OUT_OF_CORE
index a9d8e9682e8644629e1f2473dae4d86fa774e93c,c33df3592e34340f4b1a12a3884c70a4da65e5e6..3aa5fe96f08a07d7faea2e21f331a6f86c9f8aad
@@@ -55,7 -55,6 +55,7 @@@
  /* Tag variable y as being from unit x: */
  #define CMK_TAG(x,y) x##y##_
  
- #define USE_MEMPOOL_ISOMALLOC 0
++#define USE_MEMPOOL_ISOMALLOC 1
  
  #include "pup_c.h"
  
@@@ -1205,36 -1204,36 +1205,6 @@@ void   CmiHandleMessage(void *msg)
  /** @} */
  
  
--/****** Isomalloc: Migratable Memory Allocation ********/
--/*Simple block-by-block interface:*/
--void *CmiIsomalloc(int sizeInBytes);
--void *CmiIsomallocAlign(size_t align, size_t size);
--void  CmiIsomallocPup(pup_er p,void **block);
--void  CmiIsomallocFree(void *block);
--int   CmiIsomallocEnabled();
--void  CmiEnableIsomalloc();
--void  CmiDisableIsomalloc();
--
--CmiInt8   CmiIsomallocLength(void *block);
--int   CmiIsomallocInRange(void *addr);
--
--/*List-of-blocks interface:*/
--struct CmiIsomallocBlockList {/*Circular doubly-linked list of blocks:*/
--      struct CmiIsomallocBlockList *prev,*next;
--      /*actual data of block follows here...*/
--};
--typedef struct CmiIsomallocBlockList CmiIsomallocBlockList;
--
--/*Build/pup/destroy an entire blockList.*/
--CmiIsomallocBlockList *CmiIsomallocBlockListNew(void);
--void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **l);
--void CmiIsomallocBlockListDelete(CmiIsomallocBlockList *l);
--
--/*Allocate/free a block from this blockList*/
--void *CmiIsomallocBlockListMalloc(CmiIsomallocBlockList *l,size_t nBytes);
--void *CmiIsomallocBlockListMallocAlign(CmiIsomallocBlockList *l,size_t align,size_t nBytes);
--void CmiIsomallocBlockListFree(void *doomedMallocedBlock);
--
  /****** CTH: THE LOW-LEVEL THREADS PACKAGE ******/
  
  typedef struct CthThreadStruct *CthThread;
@@@ -1369,6 -1368,6 +1339,36 @@@ void CthAddListener(CthThread th,struc
  */
  void CthUserAddListeners(CthThread th);
  
++/****** Isomalloc: Migratable Memory Allocation ********/
++/*Simple block-by-block interface:*/
++void *CmiIsomalloc(int sizeInBytes, CthThread tid);
++void *CmiIsomallocAlign(size_t align, size_t size, CthThread t);
++void  CmiIsomallocPup(pup_er p,void **block);
++void  CmiIsomallocFree(void *block);
++int   CmiIsomallocEnabled();
++void  CmiEnableIsomalloc();
++void  CmiDisableIsomalloc();
++
++CmiInt8   CmiIsomallocLength(void *block);
++int   CmiIsomallocInRange(void *addr);
++
++/*List-of-blocks interface:*/
++struct CmiIsomallocBlockList {/*Circular doubly-linked list of blocks:*/
++      struct CmiIsomallocBlockList *prev,*next;
++      /*actual data of block follows here...*/
++};
++typedef struct CmiIsomallocBlockList CmiIsomallocBlockList;
++
++/*Build/pup/destroy an entire blockList.*/
++CmiIsomallocBlockList *CmiIsomallocBlockListNew(CthThread t);
++void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **l, CthThread tid);
++void CmiIsomallocBlockListDelete(CmiIsomallocBlockList *l);
++
++/*Allocate/free a block from this blockList*/
++void *CmiIsomallocBlockListMalloc(CmiIsomallocBlockList *l,size_t nBytes);
++void *CmiIsomallocBlockListMallocAlign(CmiIsomallocBlockList *l,size_t align,size_t nBytes);
++void CmiIsomallocBlockListFree(void *doomedMallocedBlock);
++
  
  /****** CTH: THREAD-PRIVATE VARIABLES ******/
  
index 494dd0fa501b48a60e1c69b8cb869cc6c25b940d,7281aff872feaf1c58afc9dc6a7e728e08146cc2..e195280f73fcb02d7bf4ef26066b13d0b0163109
@@@ -58,8 -58,8 +58,8 @@@ extern ELFXX_TYPE_Dyn _DYNAMIC[];      
  
  /****************** Global Variable Understanding *********************/
  /**
-- Keeps a list of global variables.
--*/
++  Keeps a list of global variables.
++  */
  class CtgGlobalList
  {
    int datalen; ///< Number of bytes in the table of global data.
    };
    CkVec<CtgRec> rec;
    int nRec;
--public:
++  public:
    /**
--   Analyze the current set of global variables, determine 
--   which are user globals and which are system globals, 
--   and store the list of user globals. 
--  */
++    Analyze the current set of global variables, determine 
++    which are user globals and which are system globals, 
++    and store the list of user globals. 
++    */
    CtgGlobalList();
--  
++
    /// Return the number of bytes needed to store our global data.
    inline int getSize(void) const {return datalen;}
--  
++
    /// Copy the current set of global data into this set,
    ///   which must be getSize() bytes.
    void read(void *datav) const;
--  
++
    /// copy data to globals
    inline void install(void *datav) const {
      char *data=(char *)datav;
@@@ -94,7 -94,7 +94,7 @@@
        memcpy((void *)rec[i].got, data+rec[i].off, rec[i].size);
      }
    }
--  
++
    inline void install_var(void *datav, void *ptr) const {
      char *data=(char *)datav;
      for (int i=0;i<nRec;i++) {
    }
  
    void read_var(void *datav, void *ptr) const;
--  
--private:
++
++  private:
    /* Return 1 if this is the name of a user global variable;
       0 if this is the name of some other (Charm or system)
       global variable. */
  };
  
  int CtgGlobalList::isUserSymbol(const char *name) {
--    // return 1;
--    if((strncmp("_", name, 1) == 0) || (strncmp("Cpv_", name, 4) == 0)
--       || (strncmp("Csv_", name, 4) == 0) || (strncmp("Ctv_", name, 4) == 0)
--       || (strncmp("Bnv_", name, 4) == 0) || (strncmp("Bpv_", name, 4) == 0)
--       || (strncmp("ckout", name, 5) == 0) || (strncmp("stdout", name, 6) == 0)
--       || (strncmp("environ", name, 7) == 0)
--       || (strncmp("stderr", name, 6) == 0) || (strncmp("stdin", name, 5) == 0))
--        return 0;
--    
--    return 1;
++  // return 1;
++  if((strncmp("_", name, 1) == 0) || (strncmp("Cpv_", name, 4) == 0)
++      || (strncmp("Csv_", name, 4) == 0) || (strncmp("Ctv_", name, 4) == 0)
++      || (strncmp("Bnv_", name, 4) == 0) || (strncmp("Bpv_", name, 4) == 0)
++      || (strncmp("ckout", name, 5) == 0) || (strncmp("stdout", name, 6) == 0)
++      || (strncmp("environ", name, 7) == 0)
++      || (strncmp("stderr", name, 6) == 0) || (strncmp("stdin", name, 5) == 0))
++    return 0;
++
++  return 1;
  }
  
  void CtgGlobalList::read(void *datav) const {
--    char *data=(char *)datav;
--    for (int i=0;i<nRec;i++) {
--      memcpy(data+rec[i].off, (void *)rec[i].got, rec[i].size);
--    }
++  char *data=(char *)datav;
++  for (int i=0;i<nRec;i++) {
++    memcpy(data+rec[i].off, (void *)rec[i].got, rec[i].size);
++  }
  }
  
  void CtgGlobalList::read_var(void *datav, void *ptr) const {
--    char *data=(char *)datav;
--    for (int i=0;i<nRec;i++) {
--      long offset = (char*)ptr-(char *)rec[i].got;
--      if (offset >= 0 && offset < rec[i].size) {
--        memcpy(data+rec[i].off, (void *)rec[i].got, rec[i].size);
--        break;
--      }
++  char *data=(char *)datav;
++  for (int i=0;i<nRec;i++) {
++    long offset = (char*)ptr-(char *)rec[i].got;
++    if (offset >= 0 && offset < rec[i].size) {
++      memcpy(data+rec[i].off, (void *)rec[i].got, rec[i].size);
++      break;
      }
++  }
  }
  
  CkVec<char *>  _namelist;
@@@ -154,59 -154,59 +154,59 @@@ extern "C" int lookup_obj_sym(char *nam
  // read from a file called "globals"
  static void readGlobals()
  {
--    if (loaded) return;
--    const char *fname = "globals";
--printf("Loading globals from file \"%s\" ... \n", fname);
--    FILE *gf = fopen(fname, "r");
--    if (gf == NULL) {
--      CmiAbort("Failed to load globals, file may not exist!");
--    }
--    while (!feof(gf)) 
--    {
--      char name[1024];
--      fscanf(gf, "%s\n", name);
--      _namelist.push_back(strdup(name));
--    }
--    fclose(gf);
--    loaded = 1;
++  if (loaded) return;
++  const char *fname = "globals";
++  printf("Loading globals from file \"%s\" ... \n", fname);
++  FILE *gf = fopen(fname, "r");
++  if (gf == NULL) {
++    CmiAbort("Failed to load globals, file may not exist!");
++  }
++  while (!feof(gf)) 
++  {
++    char name[1024];
++    fscanf(gf, "%s\n", name);
++    _namelist.push_back(strdup(name));
++  }
++  fclose(gf);
++  loaded = 1;
  }
  
  
  /**
--   Analyze the current set of global variables, determine 
--   which are user globals and which are system globals, 
--   and store the list of user globals. 
-- */
++  Analyze the current set of global variables, determine 
++  which are user globals and which are system globals, 
++  and store the list of user globals. 
++  */
  CtgGlobalList::CtgGlobalList() {
--    datalen=0;
--    nRec=0;
--    
--    int count;
--    for (count = 0; count < _namelist.size(); count ++) 
--    {
--      unsigned long addr;
--        int size;
--      if (0 > lookup_obj_sym(_namelist[count], &addr, &size)) {
--              fprintf(stderr, "%s: no such symbol\n", _namelist[count]);
--              continue;
--      }
--        void *ptr = (void *)addr;
--        int gSize = ALIGN8(size);
--                  
--//#if DEBUG_GOT_MANAGER
--            printf("   -> %s is a user global, of size %d, at %p\n",
--            _namelist[count], size, ptr);
--//#endif
--                  
--      rec.push_back(CtgRec(ptr,datalen,size));
--      datalen+=gSize;
++  datalen=0;
++  nRec=0;
++
++  int count;
++  for (count = 0; count < _namelist.size(); count ++) 
++  {
++    unsigned long addr;
++    int size;
++    if (0 > lookup_obj_sym(_namelist[count], &addr, &size)) {
++      fprintf(stderr, "%s: no such symbol\n", _namelist[count]);
++      continue;
      }
++    void *ptr = (void *)addr;
++    int gSize = ALIGN8(size);
++
++    //#if DEBUG_GOT_MANAGER
++    printf("   -> %s is a user global, of size %d, at %p\n",
++        _namelist[count], size, ptr);
++    //#endif
++
++    rec.push_back(CtgRec(ptr,datalen,size));
++    datalen+=gSize;
++  }
++
++  nRec=rec.size();
  
--    nRec=rec.size();
--    
  #if DEBUG_GOT_MANAGER   
--    printf("relt has %d entries, %d of which are user globals\n\n", 
--      relt_size,nRec);
++  printf("relt has %d entries, %d of which are user globals\n\n", 
++      relt_size,nRec);
  #endif
  }
  
  CpvStaticDeclare(CtgGlobals,_curCtg);
  
  struct CtgGlobalStruct {
--public:
++  public:
      /* This is set when our data is pointed to by the current GOT */
      int installed;
      int inited;
      /* Pointer to our global data segment. */
      void *data_seg;  
      int seg_size; /* size in bytes of data segment */
--    
++
      void allocate(int size) {
        seg_size=size;
--        /* global data segment need to be isomalloc */
++      /* global data segment need to be isomalloc */
        if (CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC))
          data_seg=CmiIsomalloc(seg_size);
        else
          data_seg=malloc(seg_size);
        inited = 0;
      }
--    
++
      CtgGlobalStruct(void) {
        installed=0;
        data_seg=0;
          free(data_seg);
        }
      }
--    
++
      void pup(PUP::er &p);
  };
  
  void CtgGlobalStruct::pup(PUP::er &p) {
--    p | seg_size;
--        /* global data segment need to be isomalloc pupped */
--    if (CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC))
-       //CmiIsomallocPup(&p, &data_seg);
-       pub_bytes(&p, &data_seg,sizeof(char*));
 -      CmiIsomallocPup(&p, &data_seg);
--    else {
--      if (p.isUnpacking()) allocate(seg_size);
--      p((char *)data_seg, seg_size);
--    }
++  p | seg_size;
++  /* global data segment need to be isomalloc pupped */
++  if (CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC))
++    //CmiIsomallocPup(&p, &data_seg);
++    pub_bytes(&p, &data_seg,sizeof(char*));
++  else {
++    if (p.isUnpacking()) allocate(seg_size);
++    p((char *)data_seg, seg_size);
++  }
  }
  
  /// Singleton object describing our global variables:
@@@ -267,94 -266,94 +267,94 @@@ extern "C" int init_symtab(char *exenam
  
  /** Initialize the globals support (called on each processor). */
  void CtgInit(void) {
--        CpvInitialize(int, CmiPICMethod);
--        CpvAccess(CmiPICMethod) = 2;
--      CpvInitialize(CtgGlobal,_curCtg);
--      
--      if (!_ctgList) 
--      {
--      /*
--        First call on this node: parse out our globals:
--      */
--                readGlobals();
--              init_symtab(CkGetArgv()[0]);
--
--              CtgGlobalList *l=new CtgGlobalList;
--              CtgGlobalStruct *g=new CtgGlobalStruct;
--              if (CmiMyNode()==0) {
--                      CmiPrintf("CHARM> -copyglobals enabled\n");
--              }
--              
--              g->allocate(l->getSize());
--              l->read(g->data_seg);
--              l->install(g->data_seg);
--              _ctgList=l;
--              _ctgListGlobals=g;
--      }
--        /* CmiNodeAllBarrier();  no smp anyway */
--      
--      CpvAccess(_curCtg)=_ctgListGlobals;
++  CpvInitialize(int, CmiPICMethod);
++  CpvAccess(CmiPICMethod) = 2;
++  CpvInitialize(CtgGlobal,_curCtg);
++
++  if (!_ctgList) 
++  {
++    /*
++       First call on this node: parse out our globals:
++       */
++    readGlobals();
++    init_symtab(CkGetArgv()[0]);
++
++    CtgGlobalList *l=new CtgGlobalList;
++    CtgGlobalStruct *g=new CtgGlobalStruct;
++    if (CmiMyNode()==0) {
++      CmiPrintf("CHARM> -copyglobals enabled\n");
++    }
++
++    g->allocate(l->getSize());
++    l->read(g->data_seg);
++    l->install(g->data_seg);
++    _ctgList=l;
++    _ctgListGlobals=g;
++  }
++  /* CmiNodeAllBarrier();  no smp anyway */
++
++  CpvAccess(_curCtg)=_ctgListGlobals;
  }
  
  /** Copy the current globals into this new set */
  CtgGlobals CtgCreate(void) {
--      CtgGlobalStruct *g=new CtgGlobalStruct;
--      g->allocate(_ctgList->getSize());
--      _ctgList->read(g->data_seg);
--      return g;
++  CtgGlobalStruct *g=new CtgGlobalStruct;
++  g->allocate(_ctgList->getSize());
++  _ctgList->read(g->data_seg);
++  return g;
  }
  
  /** PUP this (not currently installed) globals set */
  CtgGlobals CtgPup(pup_er pv, CtgGlobals g) {
--      PUP::er *p=(PUP::er *)pv;
--      if (p->isUnpacking()) g=new CtgGlobalStruct;
--      if (g->installed) 
--              CmiAbort("CtgPup called on currently installed globals!\n");
--      g->pup(*p);
--      if (g->seg_size!=_ctgList->getSize())
--              CmiAbort("CtgPup: global variable size changed during migration!\n");
--      return g;
++  PUP::er *p=(PUP::er *)pv;
++  if (p->isUnpacking()) g=new CtgGlobalStruct;
++  if (g->installed) 
++    CmiAbort("CtgPup called on currently installed globals!\n");
++  g->pup(*p);
++  if (g->seg_size!=_ctgList->getSize())
++    CmiAbort("CtgPup: global variable size changed during migration!\n");
++  return g;
  }
  
  /** Install this set of globals. If g==NULL, returns to original globals. */
  void CtgInstall(CtgGlobals g) {
--      CtgGlobals *cur=&CpvAccess(_curCtg);
--      CtgGlobals oldG=*cur;
--      if (g==NULL) g=_ctgListGlobals;
--      if (g == oldG) return;
--        if (oldG) {
--          _ctgList->read(oldG->data_seg);             /* store globals to own copy */
--        }
--      *cur=g;
--      oldG->installed=0;
--      _ctgList->install(g->data_seg);
--      g->installed=1;
++  CtgGlobals *cur=&CpvAccess(_curCtg);
++  CtgGlobals oldG=*cur;
++  if (g==NULL) g=_ctgListGlobals;
++  if (g == oldG) return;
++  if (oldG) {
++    _ctgList->read(oldG->data_seg);             /* store globals to own copy */
++  }
++  *cur=g;
++  oldG->installed=0;
++  _ctgList->install(g->data_seg);
++  g->installed=1;
  }
  
  /** Delete this (not currently installed) set of globals. */
  void CtgFree(CtgGlobals g) {
--      if (g->installed) CmiAbort("CtgFree called on currently installed globals!\n");
--      delete g;
++  if (g->installed) CmiAbort("CtgFree called on currently installed globals!\n");
++  delete g;
  }
  
  CtgGlobals CtgCurrentGlobals(void){
--      return CpvAccess(_curCtg);
++  return CpvAccess(_curCtg);
  }
  
  void CtgInstall_var(CtgGlobals g, void *ptr) {
--        CtgGlobals *cur=&CpvAccess(_curCtg);
--      CtgGlobals oldG = *cur;
--        if (oldG)
--        _ctgList->read_var(oldG->data_seg, ptr);
--        _ctgList->install_var(g->data_seg, ptr);             /* store globals to own copy */
++  CtgGlobals *cur=&CpvAccess(_curCtg);
++  CtgGlobals oldG = *cur;
++  if (oldG)
++    _ctgList->read_var(oldG->data_seg, ptr);
++  _ctgList->install_var(g->data_seg, ptr);             /* store globals to own copy */
  }
  
  void CtgUninstall_var(CtgGlobals g, void *ptr) {
--        CtgGlobals *cur=&CpvAccess(_curCtg);
--      CtgGlobals oldG = *cur;
--        if (oldG)
--        _ctgList->read_var(g->data_seg, ptr);             /* store globals to own copy */
--        _ctgList->install_var(oldG->data_seg, ptr);             /* store globals to own copy */
++  CtgGlobals *cur=&CpvAccess(_curCtg);
++  CtgGlobals oldG = *cur;
++  if (oldG)
++    _ctgList->read_var(g->data_seg, ptr);             /* store globals to own copy */
++  _ctgList->install_var(oldG->data_seg, ptr);             /* store globals to own copy */
  }
  
  #else     /* no ELF */
index 11ffbc0b4da11bef227ff58be890e0b1040cc594,b371a6ad980bd7e429d713e08b76126cd3e0c94b..c65a563877bde9671d803aa4e48fce5d83c50cfa
@@@ -44,10 -44,16 +44,10 @@@ added by Ryan Mokos in July 2008
  #include "converse.h"
  #include "memory-isomalloc.h"
  
--#define CMK_THREADS_DEBUG 0
 -
 -/* 0: do not use the intermediate mapregion management
 -   1: use the intermediate mapregion management  */
 -#ifndef USE_MAPREGION
 -#define USE_MAPREGION      0
 -#endif
++#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 */
@@@ -1261,7 -1278,7 +1261,7 @@@ static void print_list_array(slotset *s
    }
  }
  
--#if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
  static void print_slots(slotset *ss) {
    print_btree_top_down(ss->btree_root);
    print_list_array(ss);
@@@ -1439,16 -1456,16 +1439,16 @@@ free_slots(slotset *ss, CmiInt8 sslot, 
  
  /*
   * 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;
@@@ -1597,7 -2010,7 +1597,7 @@@ map_slots(CmiInt8 slot, CmiInt8 nslots
  
    if (pa==NULL)
    { /*Map just failed completely*/
--#if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
      perror("mmap failed");
      CmiPrintf("[%d] tried to mmap %p, but encountered error\n",CmiMyPe(),addr);
  #endif
    }
    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;
  }
@@@ -1626,11 -2311,12 +1626,11 @@@ unmap_slots(CmiInt8 slot, CmiInt8 nslot
  {
    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
  }
 -#endif 
  
  static void map_failed(CmiInt8 s,CmiInt8 n)
  {
  
  CpvStaticDeclare(slotset *, myss); /*My managed slots*/
  
-   printf("Alloc slot long %lld from %p to %p\n",s,newaddr,newaddr+*size);
 +#if USE_MEMPOOL_ISOMALLOC
 +CtvStaticDeclare(mempool_type *, threadpool); /*Thread managed pools*/
 +
 +//alloc function to be used by mempool
 +void * isomallocfn (size_t *size, gni_mem_handle_t *mem_hndl)
 +{
 +  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);
 +  *mem_hndl = s;
 +  *size = n*slotsize;
-   printf("Free slots at %p for slot %lld\n", ptr, mem_hndl); 
 +  return newaddr;
 +}
 +
 +//free function to be used by mempool
 +void isofreefn(void *ptr, gni_mem_handle_t mem_hndl)
 +{
 +  call_munmap(ptr, ((mempool_block *)ptr)->size);
 +}
 +#endif
 +
  /*This struct describes a range of virtual addresses*/
  typedef struct {
    char *start; /*First byte of region*/
@@@ -1730,7 -2376,7 +1728,7 @@@ static int bad_location(char *loc) 
    void *addr;
    addr=call_mmap_fixed(loc,slotsize);
    if (addr==NULL || addr!=loc) {
--#if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
      CmiPrintf("[%d] Skipping unmappable space at %p\n",CmiMyPe(),loc);
  #endif
      return 1; /*No good*/
@@@ -1759,7 -2405,7 +1757,7 @@@ static int partially_good(char *start,m
  static int good_range(char *start,memRange_t len,int n) {
    int i;
    memRange_t quant=divide_range(len,n);
--#if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
    CmiPrintf("good_range: %lld, %d\n", quant, n);
  #endif
    CmiAssert (quant > 0);
@@@ -1800,15 -2446,15 +1798,15 @@@ static void check_range(char *start,cha
    }
  #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);
    }
    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
  
@@@ -1863,90 -2509,90 +1861,90 @@@ static memRegion_t find_free_region(mem
  }
  
  /*
 -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=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; 
 +  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 */
 +  regions[nRegions++].len=2u*gig;   /* on bluedrop, don't mess with the lower memory region */
  #else
 -    regions[nRegions++].len=16u*meg;
 +  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="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 (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="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="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="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="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; 
 +  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;
 +  _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;
 +  }
  }
  
  static int try_largest_mmap_region(memRegion_t *destRegion)
    if (sizeof(size_t) >= 8) size = size>>2;  /* 25% of machine address space! */
    while (1) { /* test out an allocation of this size */
  #if CMK_HAS_MMAP
 -      range=mmap(NULL,size,PROT_READ|PROT_WRITE,
 -                   MAP_PRIVATE
 +    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
 +        |MAP_NORESERVE
  #endif
 -                     ,-1,0);
 +        ,-1,0);
  #else
 -        range = bad_alloc;
 +    range = bad_alloc;
  #endif
 -        if (range == bad_alloc) {  /* mmap failed */
 -#if CMK_THREADS_DEBUG
 -                /* CmiPrintf("[%d] test failed at size: %llu error: %d\n", CmiMyPe(), size, errno);  */
 +    if (range == bad_alloc) {  /* mmap failed */
- #if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
 +      /* CmiPrintf("[%d] test failed at size: %llu error: %d\n", CmiMyPe(), size, errno);  */
  #endif
  #if CMK_HAS_USLEEP
 -                if (retry++ < 5) { usleep(rand()%10000); continue; }
 -                else retry = 0;
 +      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 CMK_THREADS_DEBUG
 -               CmiPrintf("[%d] available: %p, %lld\n", CmiMyPe(), range, size);
 +      size=(double)size/shrink; /* shrink request */
 +      if (size<=0) return 0; /* mmap doesn't work */
 +    }
 +    else { /* this allocation size is available */
- #if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
 +      CmiPrintf("[%d] available: %p, %lld\n", CmiMyPe(), range, size);
  #endif
 -             call_munmap(range,size); /* needed/wanted? */
 -              if (size > good_size) {
 -                good_range = range;
 -                good_size = size;
 -                size=((double)size)*1.1;
 -                continue;
 -              }
 -              break;
 -      }
 +      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;
@@@ -2031,162 -2693,169 +2029,162 @@@ static void init_ranges(char **argv
    if (pagesize < CMK_MEMORY_PAGESIZE)
      pagesize = CMK_MEMORY_PAGESIZE;
    slotsize=(slotsize+pagesize-1) & ~(pagesize-1);
 -#endif
  
--#if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
    if (CmiMyPe() == 0)
 -  CmiPrintf("[%d] Using slotsize of %d\n", CmiMyPe(), slotsize);
 +    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 (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);
 -        }
 +
 +    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);
        }
 +    }
  
  #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 CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
 +      CmiPrintf("[%d] Isomalloc memory region: %p - %p (%d megs)\n",CmiMyPe(),
 +          freeRegion.start,freeRegion.start+freeRegion.len,
 +          freeRegion.len/meg);
  #endif
 -      }
 +    }
    }             /* end if myrank == 0 */
  
    CmiNodeAllBarrier();
  
 -    /*
 -       on some machines, isomalloc memory regions on different nodes 
 -       can be different. use +isomalloc_sync to calculate the
 -       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];
 +    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];
  
 -            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", 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 (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++;
  #ifndef __MINGW_H
 -                CMK_CPV_IS_SMP
 +            CMK_CPV_IS_SMP
  #endif
 -                ;
 -              }
 -              if (fd == -1) {
 -                CmiAbort("isomalloc_sync failed, make sure you have a shared file system.");
 -              }
 -              read(fd, &ss, sizeof(CmiUInt8));
 -              read(fd, &ee, sizeof(CmiUInt8));
 -#if CMK_THREADS_DEBUG
 -              if (CmiMyPe() == 0) CmiPrintf("[%d] load node %d isomalloc region: %lx %lx. \n",
 -                               CmiMyPe(), i, ss, ee);
 +              ;
 +          }
 +          if (fd == -1) {
 +            CmiAbort("isomalloc_sync failed, make sure you have a shared file system.");
 +          }
 +          read(fd, &ss, sizeof(CmiUInt8));
 +          read(fd, &ee, sizeof(CmiUInt8));
- #if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
 +          if (CmiMyPe() == 0) CmiPrintf("[%d] load node %d isomalloc region: %lx %lx. \n",
 +              CmiMyPe(), i, ss, ee);
  #endif
 -              close(fd);
 -              if (ss>s) s = ss;
 -              if (ee<e) e = ee;
 -            }
 +          close(fd);
 +          if (ss>s) s = ss;
 +          if (ee<e) e = ee;
 +        }
  
 -            CmiBarrier();
 +        CmiBarrier();
  
 -            unlink(fname);
 +        unlink(fname);
  #if CMK_HAS_SYNC && ! CMK_DISABLE_SYNC
 -            system("sync");
 +        system("sync");
  #endif
  
 -              /* 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);
 -          }   /* 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);
 +      }   /* end of barrier test */
 +    } /* end of rank 0 */
 +    else {
 +      CmiBarrier();
 +      CmiBarrier();
 +      CmiBarrier();
 +      CmiBarrier();
 +    }
    }
  
    if (CmiMyRank() == 0 && freeRegion.len > 0u)
    {
 -        /*Isomalloc covers entire unused region*/
 -        isomallocStart=freeRegion.start;
 -#if USE_MAPREGION
 -        numslots=((freeRegion.len/regionSize)/CmiNumPes())*(regionSize/slotsize);
 -        freeRegion.len = numslots*CmiNumPes()*slotsize;
 -        isomallocEnd=freeRegion.start+ freeRegion.len;
 -#else
 -        isomallocEnd=freeRegion.start+freeRegion.len;
 -        numslots=(freeRegion.len/slotsize)/CmiNumPes();
 -#endif 
 -
 -#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 CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
 +    CmiPrintf("[%d] Can isomalloc up to %lu megs per pe\n",CmiMyPe(),
 +        ((memRange_t)numslots)*slotsize/meg);
  #endif
    }
  
@@@ -2293,52 -2987,33 +2291,64 @@@ static void all_slotOP(const slotOP *op
  }
  
  /************** External interface ***************/
- void *CmiIsomalloc(int size)
 +#if USE_MEMPOOL_ISOMALLOC
-   printf("[%d] isomalloc request for %d\n",CmiMyPe(),size);
++void *CmiIsomalloc(int size, CthThread tid)
 +{
 +  CmiInt8 s,n,i;
 +  CmiIsomallocBlock *blk;
-   if(CtvAccess(threadpool) == NULL) {
-     CtvAccess(threadpool) = mempool_init(size+sizeof(CmiIsomallocBlock), 
-                                                 isomallocfn, isofreefn);
 +  if (isomallocStart==NULL) return disabled_map(size);
-   blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccess(threadpool),size+sizeof(CmiIsomallocBlock),1);
++  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(size+sizeof(CmiIsomallocBlock), 
++                                                  isomallocfn, isofreefn);
++    }
++    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(size+sizeof(CmiIsomallocBlock), 
++                                                  isomallocfn, isofreefn);
++    }
++    blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccess(threadpool),size+sizeof(CmiIsomallocBlock),1);
 +  }
-   printf("[%d] isomalloc request done for %d\n",CmiMyPe(),size);
 +  blk->slot=-1;
 +  blk->length=size;
 +  return block2pointer(blk);
 +}
 +#else
  void *CmiIsomalloc(int size)
  {
 -      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;
 +  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;
 +    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);
 +  }
 +  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.  Total requested size is (size+reserved)
   */
--static void *_isomallocAlign(size_t align, size_t size, size_t reserved)
--{
 -        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);
 -        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)
++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);
++  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()
@@@ -2507,97 -3178,64 +2516,119 @@@ void CmiIsomallocInit(char **argv
  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));
++  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 USE_MEMPOOL_ISOMALLOC
- void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp)
++void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid)
 +{
 +  mempool_block *current, *mempools_head;
 +  void *newblock;
 +  CmiInt8 slot;
 +  CmiInt8 size;
++  int i, numBlocks = 0;
 +
 +  if(!pup_isUnpacking(p)) {
-     printf("[%d] address is %p %p\n",CmiMyPe(),CtvAccess(threadpool),&(CtvAccess(threadpool)->mempools_head));
-     current = &(CtvAccess(threadpool)->mempools_head);
++#if ISOMALLOC_DEBUG
++    printf("My rank is %d Pupping for %d \n",CthSelf(),tid);
++#endif
++    current = &(CtvAccessOther(tid,threadpool)->mempools_head);
++    while(current != NULL) {
++      numBlocks++;
++      current = current->next;
++    }
++#if ISOMALLOC_DEBUG
++    printf("Number of blocks packed %d\n",numBlocks);
++#endif
++    pup_int(p,&numBlocks);
++    current = &(CtvAccessOther(tid,threadpool)->mempools_head);
 +    while(current != NULL) {
 +      pup_int8(p,&current->size);
 +      pup_int8(p,&current->mem_hndl);
 +      pup_bytes(p,current->mempool_ptr,current->size);
-       printf("[%d] Packing slot %lld size %lld at %p to %p\n",CmiMyPe(),current->mem_hndl,current->size,current->mempool_ptr,current->mempool_ptr+current->size);
++#if ISOMALLOC_DEBUG
++      printf("[%d] Packing slot %lld size %d at %p to %p\n",CmiMyPe(),current->mem_hndl,current->size,current->mempool_ptr,current->mempool_ptr+current->size);
++#endif
 +      current = current->next;
 +    }
 +  }
 +
 +  if(pup_isUnpacking(p)) {
-     pup_int8(p,&size);
-     pup_int8(p,&slot);
-     newblock = map_slots(slot,size/slotsize);
-     pup_bytes(p,newblock,size);
-     printf("[%d] slot %lld size %lld at %p to %p\n",CmiMyPe(),slot,size,newblock,newblock+size);
++    pup_int(p,&numBlocks);
++#if ISOMALLOC_DEBUG
++    printf("Number of blocks to be unpacked %d\n",numBlocks);
++#endif
++    for(i = 0; i < numBlocks; i++) { 
++      pup_int8(p,&size);
++      pup_int8(p,&slot);
++      newblock = map_slots(slot,size/slotsize);
++      pup_bytes(p,newblock,size);
++#if ISOMALLOC_DEBUG
++      printf("[%d] slot %lld size %d at %p to %p\n",CmiMyPe(),slot,size,newblock,newblock+size);
++#endif
++      }
 +  }
 +  pup_bytes(p,lp,sizeof(int*));
 +  if(pup_isDeleting(p)) {
-     mempool_destroy(CtvAccess(threadpool));
++    mempool_destroy(CtvAccessOther(tid,threadpool));
 +    *lp=NULL;
 +  }
 +}
 +#else
- void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp)
++void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CmiInt8 tid=-1)
  {
 -        /* BIGSIM_OOC DEBUGGING */
 -      /* if(!pup_isUnpacking(p)) print_myslots(); */
 +  /* BIGSIM_OOC DEBUGGING */
 +  /* if(!pup_isUnpacking(p)) print_myslots(); */
  
 -      int i,nBlocks=0;
 -      CmiIsomallocBlockList *cur=NULL, *start=*lp;
 +  int i,nBlocks=0;
 +  CmiIsomallocBlockList *cur=NULL, *start=*lp;
  #if 0 /*#ifndef CMK_OPTIMIZE*/
 -      if (CpvAccess(isomalloc_blocklist)!=NULL)
 -              CmiAbort("Called CmiIsomallocBlockListPup while a blockList is active!\n"
 -                      "You should swap out the active blocklist before pupping.\n");
 +  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(); */
 +  /*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
  
  /*Delete all the blocks in this list.*/
  void CmiIsomallocBlockListDelete(CmiIsomallocBlockList *l)
  /*Allocate a block from this blockList*/
  void *CmiIsomallocBlockListMalloc(CmiIsomallocBlockList *l,size_t nBytes)
  {
 -    CmiIsomallocBlockList *n; /*Newly created slot*/
 -      n=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(CmiIsomallocBlockList)+nBytes);
 -      /*Link the new block into the circular blocklist*/
 -      n->prev=l;
 -      n->next=l->next;
 -      l->next->prev=n;
 -      l->next=n;
 -      return Slot_toUser(n);
 +  CmiIsomallocBlockList *n; /*Newly created slot*/
-   n=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(CmiIsomallocBlockList)+nBytes);
++  n=(CmiIsomallocBlockList *)CmiIsomalloc(sizeof(CmiIsomallocBlockList)+nBytes,NULL);
 +  /*Link the new block into the circular blocklist*/
 +  n->prev=l;
 +  n->next=l->next;
 +  l->next->prev=n;
 +  l->next=n;
 +  return Slot_toUser(n);
  }
  
  /*Allocate a block from this blockList with alighment */
  void *CmiIsomallocBlockListMallocAlign(CmiIsomallocBlockList *l,size_t align,size_t nBytes)
  {
 -    CmiIsomallocBlockList *n; /*Newly created slot*/
 -      n=(CmiIsomallocBlockList *)_isomallocAlign(align,nBytes,sizeof(CmiIsomallocBlockList));
 -      /*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);
 +  CmiIsomallocBlockList *n; /*Newly created slot*/
-   n=(CmiIsomallocBlockList *)_isomallocAlign(align,nBytes,sizeof(CmiIsomallocBlockList));
++  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*/
index 72a8a03116c3e0bb013cc9e2df1e03447663790e,72a8a03116c3e0bb013cc9e2df1e03447663790e..9083855d81c474e09df3076d2649f190dec24576
@@@ -1090,7 -1090,7 +1090,7 @@@ static void print_list_array(slotset *s
    }
  }
  
--#if CMK_THREADS_DEBUG
++#if ISOMALLOC_DEBUG
  static void print_slots(slotset *ss) {
    print_btree_top_down(ss->btree_root);
    print_list_array(ss);
index c6143245353a119c26844652ee642e031876d4c3,062f7411dddafc0f6f30e79f7adcc5176c231515..1c4f151fae899f2ae55a63280b30eb1e7206d282
@@@ -5,7 -5,7 +5,7 @@@
   * $Revision$
   *****************************************************************************/
  
-- /**************************************************************************
++/**************************************************************************
   *
   * typedef CthThread
   *
   *     This specifies the scheduling functions to be used for thread 't'.
   *     The scheduling functions must have the following prototypes:
   *
-- *          void awakenfn(CthThread t);
-- *          CthThread choosefn();
-- *
-- *     These functions must be provided on a per-thread basis.  (Eg, if you
-- *     CthAwaken a thread X, then X's awakefn will be called.  If a thread Y
-- *     calls CthSuspend, then Y's choosefn will be called to pick the next
-- *     thread.)  Of course, you may use the same functions for all threads
-- *     (the common case), but the specification on a per-thread basis gives
-- *     you maximum flexibility in controlling scheduling.
-- *
-- *     See also: common code, CthSetStrategyDefault.
-- *
-- * void CthYield()
-- *
-- *   - simply executes { CthAwaken(CthSelf()); CthSuspend(); }.  This
-- *     combination gives up control temporarily, but ensures that control
-- *     will eventually return.
-- *
-- *
-- * Note: there are several possible ways to implement threads.   
-- *****************************************************************************/
-- 
++*          void awakenfn(CthThread t);
++*          CthThread choosefn();
++*
++*     These functions must be provided on a per-thread basis.  (Eg, if you
++    *     CthAwaken a thread X, then X's awakefn will be called.  If a thread Y
++    *     calls CthSuspend, then Y's choosefn will be called to pick the next
++    *     thread.)  Of course, you may use the same functions for all threads
++*     (the common case), but the specification on a per-thread basis gives
++*     you maximum flexibility in controlling scheduling.
++*
++*     See also: common code, CthSetStrategyDefault.
++  *
++* void CthYield()
++  *
++  *   - simply executes { CthAwaken(CthSelf()); CthSuspend(); }.  This
++  *     combination gives up control temporarily, but ensures that control
++  *     will eventually return.
++  *
++  *
++  * Note: there are several possible ways to implement threads.   
++  *****************************************************************************/
++
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include "cmitls.h"
  #endif
  
--/**************************** Shared Base Thread Class ***********************/
--/*
--      FAULT_EVAC
--      Moved the cmicore converse header from CthThreadBase to CthThreadToken.
--      The CthThreadToken gets enqueued in the converse queue instead of the
--      CthThread. This allows the thread to be moved out of a processor even
--      if there is an awaken call for it enqueued in the scheduler
++  /**************************** Shared Base Thread Class ***********************/
++  /*
++     FAULT_EVAC
++     Moved the cmicore converse header from CthThreadBase to CthThreadToken.
++     The CthThreadToken gets enqueued in the converse queue instead of the
++     CthThread. This allows the thread to be moved out of a processor even
++     if there is an awaken call for it enqueued in the scheduler
  
  */
  
  #define THD_MAGIC_NUM 0x12345678
  
--typedef struct CthThreadBase
++  typedef struct CthThreadBase
  {
    CthThreadToken *token; /* token that shall be enqueued into the ready queue*/
    int scheduled;       /* has this thread been added to the ready queue ? */
-- 
++
    CmiObjId   tid;        /* globally unique tid */
    CthAwkFn   awakenfn;   /* Insert this thread into the ready queue */
    CthThFn    choosefn;   /* Return the next ready thread */
@@@ -190,7 -190,7 +190,7 @@@ static int CmiThreadIs_flag=0
  
  int CmiThreadIs(int flag)
  {
--      return (CmiThreadIs_flag&flag)==flag;
++  return (CmiThreadIs_flag&flag)==flag;
  }
  
  /*Macros to convert between base and specific thread types*/
  
  
  CthThreadToken *CthGetToken(CthThread t){
--      return B(t)->token;
++  return B(t)->token;
  }
  
  CpvStaticDeclare(int, Cth_serialNo);
    the presence of files, at least under Linux with local disks context
    switches are still fast; the mmap overhead is less than 5us per
    switch, even for multi-megabyte stacks.
--  
--  WARNING: Does NOT work in SMP mode, because all the processors
--      on a node will try to map their stacks to the same place.
--  WARNING: Does NOT work if switching directly from one migrateable
--      thread to another, because it blows away the stack you're currently
--      running on.  The usual Charm approach of switching to the 
--      (non-migratable) scheduler thread on context switch works fine.
++
++WARNING: Does NOT work in SMP mode, because all the processors
++on a node will try to map their stacks to the same place.
++WARNING: Does NOT work if switching directly from one migrateable
++thread to another, because it blows away the stack you're currently
++running on.  The usual Charm approach of switching to the 
++(non-migratable) scheduler thread on context switch works fine.
  */
  
  #ifndef CMK_THREADS_ALIAS_STACK
@@@ -252,11 -252,11 +252,11 @@@ int CthAliasCreate(int stackSize
    fd=mkstemp(tmpName);
    if (fd==-1) CmiAbort("threads.c> Cannot create /tmp file to contain thread stack");
    unlink(tmpName); /* delete file when it gets closed */
--  
++
    /* Make file big enough for stack, by writing one byte at end */
    lseek(fd,stackSize-sizeof(lastByte),SEEK_SET);
    write(fd,&lastByte,sizeof(lastByte));
--  
++
    return fd;
  }
  
@@@ -267,43 -267,43 +267,43 @@@ void CthAliasFree(int fd) 
  #endif
  
  /**
-- CthAliasEnable brings this thread's stack into memory.
-- You must call it before accessing the thread stack, 
-- for example, before running, packing, or unpacking the stack data.
--*/
++  CthAliasEnable brings this thread's stack into memory.
++  You must call it before accessing the thread stack, 
++  for example, before running, packing, or unpacking the stack data.
++  */
  #if CMK_THREADS_ALIAS_STACK
  CthThreadBase *_curMappedStack=0;
  void CthAliasEnable(CthThreadBase *t) {
--      void *s;
--      int flags=MAP_FIXED|MAP_SHARED; /* Posix flags */
--      if (!t->isMigratable) return;
--      if (t==_curMappedStack) return; /* don't re-map */
--      _curMappedStack=t;
--      if (0) printf("Mmapping in thread %p from runtime stack %p\n",t,&s);
--      
++  void *s;
++  int flags=MAP_FIXED|MAP_SHARED; /* Posix flags */
++  if (!t->isMigratable) return;
++  if (t==_curMappedStack) return; /* don't re-map */
++  _curMappedStack=t;
++  if (0) printf("Mmapping in thread %p from runtime stack %p\n",t,&s);
++
  #if CMK_BLUEGENEL
--        /* Blue Gene/L does not have mmap */
--        /* So this depends on a hack in CNK for syscall rts_memory_alias to
--           map stack pointer to a fix address */
--        {
--        register char *dest=(char *)0x70000000; /* point stack at high memory, not user memory */
--        int alias_slot;
--        rts_memory_alias(t->stack,dest,t->stacksize,&alias_slot);
--        }
++  /* Blue Gene/L does not have mmap */
++  /* So this depends on a hack in CNK for syscall rts_memory_alias to
++     map stack pointer to a fix address */
++  {
++    register char *dest=(char *)0x70000000; /* point stack at high memory, not user memory */
++    int alias_slot;
++    rts_memory_alias(t->stack,dest,t->stacksize,&alias_slot);
++  }
  #else
--      /* Linux mmap flag MAP_POPULATE, to pre-fault in all the pages,
--         only seems to slow down overall performance. */
--      /* Linux mmap flag MAP_GROWSDOWN is rejected at runtime under 2.4.25 */
++  /* Linux mmap flag MAP_POPULATE, to pre-fault in all the pages,
++     only seems to slow down overall performance. */
++  /* Linux mmap flag MAP_GROWSDOWN is rejected at runtime under 2.4.25 */
  #if CMK_AIX
--        if (_curMappedStack) munmap(_curMappedStack->stack,_curMappedStack->stacksize);
++  if (_curMappedStack) munmap(_curMappedStack->stack,_curMappedStack->stacksize);
  #endif
--      s=mmap(t->stack,t->stacksize,
--              PROT_READ|PROT_WRITE|PROT_EXEC, /* exec for gcc nested function thunks */
--              flags, t->aliasStackHandle,0);
--      if (s!=t->stack) {
--              perror("threads.c CthAliasEnable mmap");
--              CmiAbort("threads.c CthAliasEnable mmap failed");
--      }
++  s=mmap(t->stack,t->stacksize,
++      PROT_READ|PROT_WRITE|PROT_EXEC, /* exec for gcc nested function thunks */
++      flags, t->aliasStackHandle,0);
++  if (s!=t->stack) {
++    perror("threads.c CthAliasEnable mmap");
++    CmiAbort("threads.c CthAliasEnable mmap failed");
++  }
  #endif
  }
  #else
@@@ -336,9 -336,9 +336,9 @@@ CmiObjId *CthGetThreadID(CthThread th
  char *CthGetData(CthThread t) { return B(t)->data; }
  
  /* Ensure this thread has at least enough 
--room for all the thread-local variables 
--initialized so far on this processor.
--*/
++   room for all the thread-local variables 
++   initialized so far on this processor.
++   */
  #if CMK_C_INLINE
  inline
  #endif
@@@ -356,9 -356,9 +356,9 @@@ static void CthFixData(CthThread t
  }
  
  /**
--Allocate another size bytes of thread-local storage,
--and return the offset into the thread storage buffer.
-- */
++  Allocate another size bytes of thread-local storage,
++  and return the offset into the thread storage buffer.
++  */
  int CthRegister(int size)
  {
    int datasize=CthCpvAccess(CthDatasize);
  }
  
  /**
--Make sure we have room to store up to at least maxOffset
--bytes of thread-local storage.
--*/
++  Make sure we have room to store up to at least maxOffset
++  bytes of thread-local storage.
++  */
  void CthRegistered(int maxOffset) {
    if (CthCpvAccess(CthDatasize)<maxOffset) {
      CthThreadBase *th=(CthThreadBase *)CthCpvAccess(CthCurrent);
@@@ -447,7 -447,7 +447,7 @@@ static void *CthAllocateStack(CthThread
      th->aliasStackHandle=CthAliasCreate(*stackSize);
      ret=CMK_THREADS_ALIAS_LOCATION;
  #else /* isomalloc */
--    ret=CmiIsomalloc(*stackSize);
++    ret=CmiIsomalloc(*stackSize, (CthThread)th);
  #endif
    }
    _MEMCHECK(ret);
@@@ -461,28 -461,28 +461,28 @@@ static void CthThreadBaseFree(CthThread
     * remove the token if it is not queued in the converse scheduler           
     */
    if(th->scheduled == 0){
--      free(th->token);
++    free(th->token);
    }else{
--      th->token->thread = NULL;
++    th->token->thread = NULL;
    }
    /* Call the free function pointer on all the listeners on
       this thread and also delete the thread listener objects
--  */
++     */
    for(l=th->listener;l!=NULL;l=lnext){
--      lnext=l->next;
--      l->next=0;
--      if (l->free) l->free(l);
++    lnext=l->next;
++    l->next=0;
++    if (l->free) l->free(l);
    }
    free(th->data);
    if (th->isMigratable) {
  #if CMK_THREADS_ALIAS_STACK
--        CthAliasFree(th->aliasStackHandle);
++    CthAliasFree(th->aliasStackHandle);
  #else /* isomalloc */
--        CmiIsomallocFree(th->stack);
++    //CmiIsomallocFree(th->stack);
  #endif
    } 
    else if (th->stack!=NULL) {
--        free(th->stack);
++    free(th->stack);
    }
    th->stack=NULL;
  }
@@@ -497,15 -497,15 +497,15 @@@ static void CthBaseInit(char **argv
    CthCpvInitialize(int,  _defaultStackSize);
    CthCpvAccess(_defaultStackSize)=CMK_STACKSIZE_DEFAULT;
    CmiGetArgIntDesc(argv,"+stacksize",&CthCpvAccess(_defaultStackSize),
--      "Default user-level thread stack size");  
--  
++      "Default user-level thread stack size");  
++
    CthCpvInitialize(CthThread,  CthCurrent);
    CthCpvInitialize(char *, CthData);
    CthCpvInitialize(int,        CthDatasize);
--  
++
    CthCpvAccess(CthData)=0;
    CthCpvAccess(CthDatasize)=0;
--  
++
    CpvInitialize(int, Cth_serialNo);
    CpvAccess(Cth_serialNo) = 1;
  
@@@ -524,111 -524,109 +524,111 @@@ CthThread CthSelf(
  void CthPupBase(pup_er p,CthThreadBase *t,int useMigratable)
  {
  #if CMK_ERROR_CHECKING
--      if ((CthThread)t==CthCpvAccess(CthCurrent))
--              CmiAbort("CthPupBase: Cannot pack running thread!");
++  if ((CthThread)t==CthCpvAccess(CthCurrent))
++    CmiAbort("CthPupBase: Cannot pack running thread!");
  #endif
--      /*
--       * Token will never be freed, so its pointer should be pupped.
--       * When packing, set the thread pointer in this token to be NULL.
--       * When unpacking, reset the thread pointer in token to this thread.
--       */
--        
--        if(_BgOutOfCoreFlag!=0){
--          pup_bytes(p, &t->token, sizeof(void *));
--          if(!pup_isUnpacking(p)){
--              t->token->thread = NULL;
--          }
--          pup_int(p, &t->scheduled);
--      }
--      if(pup_isUnpacking(p)){
--              if(_BgOutOfCoreFlag==0){
--                  t->token = (CthThreadToken *)malloc(sizeof(CthThreadToken));
--                  t->token->thread = S(t);
--                  t->token->serialNo = CpvAccess(Cth_serialNo)++;
--                  /*For normal runs where this pup is needed,
--                  set scheduled to 0 in the unpacking period since the thread has
--                  not been scheduled */
--                  t->scheduled = 0;
--              }else{
--              /* During out-of-core emulation */
--                  /* 
--                   * When t->scheduled is set, the thread is in the queue so the token
--                   * should be kept. Otherwise, allocate a new space for the token
--                   */
--                  if(t->scheduled==0){
--                      /*CmiPrintf("Creating a new token for %p!\n", t->token);*/
--                      t->token = (CthThreadToken *)malloc(sizeof(CthThreadToken));
--                  }
--                  t->token->thread = S(t);
--            t->token->serialNo = CpvAccess(Cth_serialNo)++;
--              }
--      }
--      
--      /*BIGSIM_OOC DEBUGGING */
--      /*if(_BgOutOfCoreFlag!=0){
--         if(pup_isUnpacking(p)){
--              CmiPrintf("Unpacking: ");
--          }else{
--              CmiPrintf("Packing: ");
--          }   
--          CmiPrintf("thd=%p, its token=%p, token's thd=%p\n", t, t->token, t->token->thread); 
--      } */
--
--      /*Really need a pup_functionPtr here:*/
--      pup_bytes(p,&t->awakenfn,sizeof(t->awakenfn));
--      pup_bytes(p,&t->choosefn,sizeof(t->choosefn));
--      pup_bytes(p,&t->next,sizeof(t->next));
--      pup_int(p,&t->suspendable);
--      pup_int(p,&t->datasize);
--      if (pup_isUnpacking(p)) { 
--              t->data = (char *) malloc(t->datasize);_MEMCHECK(t->data);
--      }
--      pup_bytes(p,(void *)t->data,t->datasize);
--      pup_int(p,&t->isMigratable);
--      pup_int(p,&t->stacksize);
--      if (t->isMigratable) {
++  /*
++   * Token will never be freed, so its pointer should be pupped.
++   * When packing, set the thread pointer in this token to be NULL.
++   * When unpacking, reset the thread pointer in token to this thread.
++   */
++
++  if(_BgOutOfCoreFlag!=0){
++    pup_bytes(p, &t->token, sizeof(void *));
++    if(!pup_isUnpacking(p)){
++      t->token->thread = NULL;
++    }
++    pup_int(p, &t->scheduled);
++  }
++  if(pup_isUnpacking(p)){
++    if(_BgOutOfCoreFlag==0){
++      t->token = (CthThreadToken *)malloc(sizeof(CthThreadToken));
++      t->token->thread = S(t);
++      t->token->serialNo = CpvAccess(Cth_serialNo)++;
++      /*For normal runs where this pup is needed,
++        set scheduled to 0 in the unpacking period since the thread has
++        not been scheduled */
++      t->scheduled = 0;
++    }else{
++      /* During out-of-core emulation */
++      /* 
++       * When t->scheduled is set, the thread is in the queue so the token
++       * should be kept. Otherwise, allocate a new space for the token
++       */
++      if(t->scheduled==0){
++        /*CmiPrintf("Creating a new token for %p!\n", t->token);*/
++        t->token = (CthThreadToken *)malloc(sizeof(CthThreadToken));
++      }
++      t->token->thread = S(t);
++      t->token->serialNo = CpvAccess(Cth_serialNo)++;
++    }
++  }
++
++  /*BIGSIM_OOC DEBUGGING */
++  /*if(_BgOutOfCoreFlag!=0){
++    if(pup_isUnpacking(p)){
++    CmiPrintf("Unpacking: ");
++    }else{
++    CmiPrintf("Packing: ");
++    } 
++    CmiPrintf("thd=%p, its token=%p, token's thd=%p\n", t, t->token, t->token->thread); 
++    } */
++
++  /*Really need a pup_functionPtr here:*/
++  pup_bytes(p,&t->awakenfn,sizeof(t->awakenfn));
++  pup_bytes(p,&t->choosefn,sizeof(t->choosefn));
++  pup_bytes(p,&t->next,sizeof(t->next));
++  pup_int(p,&t->suspendable);
++  pup_int(p,&t->datasize);
++  if (pup_isUnpacking(p)) { 
++    t->data = (char *) malloc(t->datasize);_MEMCHECK(t->data);
++  }
++  pup_bytes(p,(void *)t->data,t->datasize);
++  pup_int(p,&t->isMigratable);
++  pup_int(p,&t->stacksize);
++  if (t->isMigratable) {
  #if CMK_THREADS_ALIAS_STACK
--              if (pup_isUnpacking(p)) { 
--                      CthAllocateStack(t,&t->stacksize,1);
--              }
--              CthAliasEnable(t);
--              pup_bytes(p,t->stack,t->stacksize);
++    if (pup_isUnpacking(p)) { 
++      CthAllocateStack(t,&t->stacksize,1);
++    }
++    CthAliasEnable(t);
++    pup_bytes(p,t->stack,t->stacksize);
  #elif CMK_THREADS_USE_STACKCOPY
--              /* do nothing */
++    /* do nothing */
  #else /* isomalloc */
- //            CmiIsomallocPup(p,&t->stack);
-               pup_bytes(p,&t->stack,sizeof(char*));
 -              CmiIsomallocPup(p,&t->stack);
++    //                CmiIsomallocPup(p,&t->stack);
++    pup_bytes(p,&t->stack,sizeof(char*));
  #endif
--      
--      else {
--              if (useMigratable)
--                      CmiAbort("You must use CthCreateMigratable to use CthPup!\n");
--              /*Pup the stack pointer as raw bytes*/
--              pup_bytes(p,&t->stack,sizeof(t->stack));
--      }
--      if (pup_isUnpacking(p)) { 
--              /* FIXME:  restore thread listener */
--              t->listener = NULL;
--      }
--
--      pup_int(p, &t->magic);
++  } 
++  else {
++    if (useMigratable)
++      CmiAbort("You must use CthCreateMigratable to use CthPup!\n");
++    /*Pup the stack pointer as raw bytes*/
++    pup_bytes(p,&t->stack,sizeof(t->stack));
++  }
++  if (pup_isUnpacking(p)) { 
++    /* FIXME:  restore thread listener */
++    t->listener = NULL;
++  }
++
++  pup_int(p, &t->magic);
  
  #if CMK_THREADS_BUILD_TLS
--        void* aux;
--        pup_bytes(p, &t->tlsseg, sizeof(tlsseg_t));
--        aux = ((void*)(t->tlsseg.memseg)) - t->tlsseg.size;
--        /* fixme: tls global variables handling needs isomalloc */
-         //CmiIsomallocPup(p, &aux);
-                   pup_bytes(p,&aux,sizeof(char*));
 -        CmiIsomallocPup(p, &aux);
--        /* printf("[%d] %s %p\n", CmiMyPe(), pup_typeString(p), t->tlsseg.memseg); */
++  void* aux;
++  pup_bytes(p, &t->tlsseg, sizeof(tlsseg_t));
++  aux = ((void*)(t->tlsseg.memseg)) - t->tlsseg.size;
++  /* fixme: tls global variables handling needs isomalloc */
++  //CmiIsomallocPup(p, &aux);
++  pup_bytes(p,&aux,sizeof(char*));
++  /* printf("[%d] %s %p\n", CmiMyPe(), pup_typeString(p), t->tlsseg.memseg); */
  #endif
  
  }
  
  static void CthThreadFinished(CthThread t)
  {
--      B(t)->exiting=1;
--      CthSuspend();
++  B(t)->exiting=1;
++  CthSuspend();
  }
  
  
@@@ -658,7 -656,7 +658,7 @@@ static void CthBaseResume(CthThread t
  {
    struct CthThreadListener *l;
    for(l=B(t)->listener;l!=NULL;l=l->next){
--      if (l->resume) l->resume(l);
++    if (l->resume) l->resume(l);
    }
    CpvAccess(_numSwitches)++;
    CthFixData(t); /*Thread-local storage may have changed in other thread.*/
  
  /**
    switch the thread to t
--*/
++  */
  void CthSwitchThread(CthThread t)
  {
    CthBaseResume(t);
@@@ -686,20 -684,20 +686,20 @@@ void CthSuspend(void
  
    if (cur->suspendable == 0)
      CmiAbort("Fatal Error> trying to suspend a non-suspendable thread!\n");
--  
++
    /*
--      Call the suspend function on listeners
--  */
++     Call the suspend function on listeners
++     */
    for(l=cur->listener;l!=NULL;l=l->next){
--      if (l->suspend) l->suspend(l);
++    if (l->suspend) l->suspend(l);
    }
    if (cur->choosefn == 0) CthNoStrategy();
    next = cur->choosefn();
    /*cur->scheduled=0;*/
    /*changed due to out-of-core emulation in BigSim*/
    /** Sometimes, a CthThread is running without ever being awakened
--    * In this case, the scheduled is the initialized value "0"
--    */
++   * In this case, the scheduled is the initialized value "0"
++   */
    if(cur->scheduled > 0)
      cur->scheduled--;
  
@@@ -722,10 -720,10 +722,10 @@@ void CthAwaken(CthThread th
    if (B(th)->awakenfn == 0) CthNoStrategy();
  
    /*BIGSIM_OOC DEBUGGING
--  if(B(th)->scheduled==1){
++    if(B(th)->scheduled==1){
      CmiPrintf("====Thread %p is already scheduled!!!!\n", th);
      return;
--  } */
++    } */
  
  #if CMK_TRACE_ENABLED
  #if ! CMK_TRACE_IN_CHARM
@@@ -767,42 -765,42 +767,42 @@@ void CthYieldPrio(int s, int pb, unsign
  }
  
  /*
--      Add a new thread listener to a thread 
--*/
++   Add a new thread listener to a thread 
++   */
  void CthAddListener(CthThread t,struct CthThreadListener *l){
--              struct CthThreadListener *p=B(t)->listener;
--              if(p== NULL){ /* first listener */
--                      B(t)->listener=l;
--                      l->thread = t;
--                      l->next=NULL;
--                      return; 
--              }
--              /* Add l at end of current chain of listeners: */
--              while(p->next != NULL){
--                      p = p->next;
--              }
--              p->next = l;
--              l->next = NULL;
--              l->thread = t;
++  struct CthThreadListener *p=B(t)->listener;
++  if(p== NULL){ /* first listener */
++    B(t)->listener=l;
++    l->thread = t;
++    l->next=NULL;
++    return;   
++  }
++  /* Add l at end of current chain of listeners: */
++  while(p->next != NULL){
++    p = p->next;
++  }
++  p->next = l;
++  l->next = NULL;
++  l->thread = t;
  }
  
  /*************************** Stack-Copying Threads (obsolete) *******************
--Basic idea: switch from thread A (currently running) to thread B by copying
--A's stack from the system stack area into A's buffer in the heap, then
--copy B's stack from its heap buffer onto the system stack.
++  Basic idea: switch from thread A (currently running) to thread B by copying
++  A's stack from the system stack area into A's buffer in the heap, then
++  copy B's stack from its heap buffer onto the system stack.
  
--This allows thread migration, because the system stack is in the same
--location on every processor; but the context-switching overhead (especially
--for threads with deep stacks) is extremely high.
++  This allows thread migration, because the system stack is in the same
++  location on every processor; but the context-switching overhead (especially
++  for threads with deep stacks) is extremely high.
  
--Written by Josh Yelon around May 1999
++  Written by Josh Yelon around May 1999
  
--stack grows down like:
--lo   <- savedptr    <- savedstack
++  stack grows down like:
++  lo   <- savedptr    <- savedstack
  
--...
++  ...
  
--high <- stackbase
++  high <- stackbase
  
  NOTE: this only works when system stack base is same on all processors.
  Which is not the case on my FC4 laptop ?!
@@@ -841,23 -839,23 +841,23 @@@ int CthMigratable(
  
  CthThread CthPup(pup_er p, CthThread t)
  {
--    if (pup_isUnpacking(p))
--      { t = (CthThread) malloc(sizeof(CthThreadStruct));_MEMCHECK(t);}
--    pup_bytes(p, (void*) t, sizeof(CthThreadStruct)); 
--    CthPupBase(p,&t->base,0);
--    pup_int(p,&t->savedsize);
--    if (pup_isUnpacking(p)) {
--      t->savedstack = (qt_t*) malloc(t->savedsize);_MEMCHECK(t->savedstack);
--      t->stacklen = t->savedsize;       /* reflect actual size */
--    }
--    pup_bytes(p, (void*) t->savedstack, t->savedsize);
++  if (pup_isUnpacking(p))
++  { t = (CthThread) malloc(sizeof(CthThreadStruct));_MEMCHECK(t);}
++  pup_bytes(p, (void*) t, sizeof(CthThreadStruct)); 
++  CthPupBase(p,&t->base,0);
++  pup_int(p,&t->savedsize);
++  if (pup_isUnpacking(p)) {
++    t->savedstack = (qt_t*) malloc(t->savedsize);_MEMCHECK(t->savedstack);
++    t->stacklen = t->savedsize;       /* reflect actual size */
++  }
++  pup_bytes(p, (void*) t->savedstack, t->savedsize);
  
--      /* assume system stacks are same on all processors !! */
--    pup_bytes(p,&t->savedptr,sizeof(t->savedptr));  
++  /* assume system stacks are same on all processors !! */
++  pup_bytes(p,&t->savedptr,sizeof(t->savedptr));  
  
--    if (pup_isDeleting(p))
--      {CthFree(t);t=0;}
--    return t;
++  if (pup_isDeleting(p))
++  {CthFree(t);t=0;}
++  return t;
  }
  
  
@@@ -890,7 -888,7 +890,7 @@@ static void CthThreadFree(CthThread t
  }
  
  void CthFree(t)
--CthThread t;
++  CthThread t;
  {
    if (t==NULL) return;
    CthProcInfo proc = CthCpvAccess(CthProc);   
@@@ -922,7 -920,7 +922,7 @@@ void CthInit(char **argv
    /* leave some space for current stack frame < 256 bytes */
    /* sp must be same on all processors for migration to work ! */
    sp = (qt_t*)(((size_t)&t) & ~((size_t)0xFF));
--/*printf("[%d] System stack base: %p\n", CmiMyPe(), sp);*/
++  /*printf("[%d] System stack base: %p\n", CmiMyPe(), sp);*/
    p->stackbase = QT_SP(sp, 0x100);
  
    /* printf("sp: %p\n", sp); */
@@@ -1011,7 -1009,7 +1011,7 @@@ static void CthResume1(qt_t *sp, CthPro
  }
  
  void CthResume(t)
--CthThread t;
++  CthThread t;
  {
    CthProcInfo proc = CthCpvAccess(CthProc);
    QT_BLOCK((qt_helper_t*)CthResume1, proc, t, proc->switchbuf_sp);
@@@ -1031,12 -1029,12 +1031,12 @@@ CthThread CthCreateMigratable(CthVoidF
  }
  
  /**************************************************************************
--QuickThreads does not work on Win32-- our stack-shifting large allocas
--fail a stack depth check.  Windows NT and 98 provide a user-level thread 
--interface called "Fibers", used here.
++  QuickThreads does not work on Win32-- our stack-shifting large allocas
++  fail a stack depth check.  Windows NT and 98 provide a user-level thread 
++  interface called "Fibers", used here.
  
--Written by Sameer Paranjpye around October 2000
--*/
++  Written by Sameer Paranjpye around October 2000
++  */
  #elif  CMK_THREADS_ARE_WIN32_FIBERS
  #include <windows.h>
  #include <winbase.h>
@@@ -1071,7 -1069,7 +1071,7 @@@ CreateFiberEx
      DWORD dwFlags,
      LPFIBER_START_ROUTINE lpStartAddress,
      LPVOID lpParameter
--);
++    );
  
  
  WINBASEAPI
@@@ -1178,9 -1176,9 +1178,9 @@@ static void CthClearThreads(
      }
    }
    if (m!=p)
--  for (i=m; i<n; i++,p++) {
++    for (i=m; i<n; i++,p++) {
        CthCpvAccess(exitThreads)[p] = CthCpvAccess(exitThreads)[i];
--  }
++    }
  }
  
  void CthFree(CthThread t)
    CthCpvAccess(exitThreads)[CthCpvAccess(nExit)++] = t;
    if (t==CthCpvAccess(CthCurrent)) 
    {
--     t->base.exiting = 1;
++    t->base.exiting = 1;
    } 
    else 
    {
      CthClearThreads();
--/*  was
--    if (t->data) free(t->data);
--    DeleteFiber(t->fiber);
--    free(t);
--*/
++    /*  was
++        if (t->data) free(t->data);
++        DeleteFiber(t->fiber);
++        free(t);
++        */
    }
  }
  
  void CthFiberBlock(CthThread t)
  {
    CthThread tp;
--  
++
    SwitchToFiber(t->fiber);
    tp = CthCpvAccess(CthPrevious);
    if (tp != 0 && tp->killed == 1)
@@@ -1269,7 -1267,7 +1269,7 @@@ CthThread CthCreate(CthVoidFn fn, void 
    fiberData = (void**)malloc(2*sizeof(void *));
    fiberData[0] = (void *)fn;
    fiberData[1] = arg;
--  
++
    result = (CthThread)malloc(sizeof(struct CthThreadStruct));
    _MEMCHECK(result);
    CthThreadInit(result);
    result->fiber = CreateFiberEx(size, size, 0, FiberSetUp, (PVOID) fiberData);
    if (!result->fiber)
      CmiAbort("CthCreate failed to create fiber!\n");
--  
++
    return result;
  }
  
@@@ -1297,10 -1295,10 +1297,10 @@@ CthThread CthCreateMigratable(CthVoidF
  }
  
  /***************************************************
--Use Posix Threads to simulate cooperative user-level
--threads.  This version is very portable but inefficient.
++  Use Posix Threads to simulate cooperative user-level
++  threads.  This version is very portable but inefficient.
  
--Written by Milind Bhandarkar around November 2000
++  Written by Milind Bhandarkar around November 2000
  
  IMPORTANT:  for SUN, must link with -mt compiler flag
  Rewritten by Gengbin Zheng
@@@ -1325,11 -1323,11 +1325,11 @@@ struct CthThreadStruc
    The sched_mutex is the current token of execution.
    Only the running thread holds this lock; all other threads
    have released the lock and are waiting on their condition variable.
--*/
++  */
  CthCpvStatic(pthread_mutex_t, sched_mutex);
  
  static void CthThreadInit(t)
--CthThread t;
++  CthThread t;
  {
    CthThreadBaseInit(&t->base);
    t->inited = 0;
@@@ -1355,7 -1353,7 +1355,7 @@@ void CthInit(char **argv
  }
  
  void CthFree(t)
--CthThread t;
++  CthThread t;
  {
    if (t==NULL) return;
    if (t==CthCpvAccess(CthCurrent)) {
@@@ -1377,10 -1375,10 +1377,10 @@@ void CthResume(CthThread t
      pthread_exit(0);
    } else {
      /* pthread_cond_wait might (with low probability) return when the 
--      condition variable has not been signaled, guarded with 
--      predicate checks */
++       condition variable has not been signaled, guarded with 
++       predicate checks */
      do {
--    pthread_cond_wait(&(tc->cond), &CthCpvAccess(sched_mutex));
++      pthread_cond_wait(&(tc->cond), &CthCpvAccess(sched_mutex));
      } while (tc!=CthCpvAccess(CthCurrent)) ;
    }
  }
@@@ -1393,7 -1391,7 +1393,7 @@@ static void *CthOnly(void * arg
    pthread_mutex_lock(&CthCpvAccess(sched_mutex));
    pthread_cond_signal(th->creator);
    do {
--  pthread_cond_wait(&(th->cond), &CthCpvAccess(sched_mutex));
++    pthread_cond_wait(&(th->cond), &CthCpvAccess(sched_mutex));
    } while (arg!=CthCpvAccess(CthCurrent)) ;
    th->fn(th->arg);
    CthThreadFinished(th);
@@@ -1420,19 -1418,19 +1420,19 @@@ CthThread CthCreate(CthVoidFn fn, void 
    /* pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); */
    if (size<1024) size = CthCpvAccess(_defaultStackSize);
    if (0!=(r=pthread_attr_setstacksize(&attr,size))) {
--      if (!reported) {
--        CmiPrintf("Warning: pthread_attr_setstacksize failed\n");
--      errno = r;
--      perror("pthread_attr_setstacksize");
--        reported = 1;
--      }
++    if (!reported) {
++      CmiPrintf("Warning: pthread_attr_setstacksize failed\n");
++      errno = r;
++      perror("pthread_attr_setstacksize");
++      reported = 1;
++    }
    }
--      
++
    /* **CWL** Am assuming Gengbin left this unchanged because the macro
       re-definition of pthread_create would not happen before this part of
       the code. If the assumption is not true, then we can simply replace
       this hash-if with the else portion.
--  */
++     */
  #if CMK_WITH_TAU
    r = tau_pthread_create(&(result->self), &attr, CthOnly, (void*) result);
  #else
      CmiAbort("CthCreate failed to created a new pthread\n");
    }
    do {
--  pthread_cond_wait(&(self->cond), &CthCpvAccess(sched_mutex));
++    pthread_cond_wait(&(self->cond), &CthCpvAccess(sched_mutex));
    } while (result->inited==0);
    return result;
  }
@@@ -1464,18 -1462,18 +1464,18 @@@ CthThread CthCreateMigratable(CthVoidF
  }
  
  /***************************************************************
--Use SysV r3 setcontext/getcontext calls instead of
--quickthreads.  This works on lots of architectures (such as
--SUN, IBM SP, O2K, DEC Alpha, IA64, Cray X1, Linux with newer version of 
-- glibc such as the one with RH9) 
--On some machine such as IA64 and Cray X1, the context version is the 
--only thread package that is working. 
++  Use SysV r3 setcontext/getcontext calls instead of
++  quickthreads.  This works on lots of architectures (such as
++  SUN, IBM SP, O2K, DEC Alpha, IA64, Cray X1, Linux with newer version of 
++  glibc such as the one with RH9) 
++  On some machine such as IA64 and Cray X1, the context version is the 
++  only thread package that is working. 
  
--Porting should be easy. To port context threads, one need to set the 
--direction of the thread stack properly in conv-mach.h.
++  Porting should be easy. To port context threads, one need to set the 
++  direction of the thread stack properly in conv-mach.h.
  
  Note: on some machine like Sun and IBM SP, one needs to link with memory gnuold
-- to have this context thread working.
++to have this context thread working.
  
  Written by Gengbin Zheng around April 2001
  
@@@ -1522,7 -1520,7 +1522,7 @@@ struct CthThreadStruc
  
  
  static void CthThreadInit(t)
--CthThread t;
++  CthThread t;
  {
    CthThreadBaseInit(&t->base);
  }
@@@ -1586,7 -1584,7 +1586,7 @@@ void CthResume(CthThread) __attribute__
  #endif
  
  void CthResume(t)
--CthThread t;
++  CthThread t;
  {
    CthThread tc;
    tc = CthCpvAccess(CthCurrent);
        setJcontext(&t->context);
      }
    }
--/*This check will mistakenly fail if the thread migrates (changing tc)
--  if (tc!=CthCpvAccess(CthCurrent)) { CmiAbort("Stack corrupted?\n"); }
--*/
++  /*This check will mistakenly fail if the thread migrates (changing tc)
++    if (tc!=CthCpvAccess(CthCurrent)) { CmiAbort("Stack corrupted?\n"); }
++    */
  }
  
  #if CMK_THREADS_USE_CONTEXT && CMK_64BIT /* makecontext only pass integer arguments */
@@@ -1635,10 -1633,10 +1635,10 @@@ void CthStartThread(qt_userf_t fn,void 
    ((void *)((((qt_word_t)(sp)) + (alignment) - 1) & ~((alignment)-1)))
  
  int ptrDiffLen(const void *a,const void *b) {
--      char *ac=(char *)a, *bc=(char *)b;
--      int ret=ac-bc;
--      if (ret<0) ret=-ret;
--      return ret;
++  char *ac=(char *)a, *bc=(char *)b;
++  int ret=ac-bc;
++  if (ret<0) ret=-ret;
++  return ret;
  }
  
  static CthThread CthCreateInner(CthVoidFn fn,void *arg,int size,int migratable)
  #endif
    CthAllocateStack(&result->base,&size,migratable);
    stack = result->base.stack;
--  
++
    if (0 != getJcontext(&result->context))
      CmiAbort("CthCreateInner: getcontext failed.\n");
  
    ss_end = stack + size;
  
--/**
-- Decide where to point the uc_stack.ss_sp field of our "context"
-- structure.  The configuration values CMK_CONTEXT_STACKBEGIN, 
-- CMK_CONTEXT_STACKEND, and CMK_CONTEXT_STACKMIDDLE determine where to
-- point ss_sp: to the beginning, end, and middle of the stack buffer
-- respectively.  The default, used by most machines, is CMK_CONTEXT_STACKBEGIN.
--*/
++  /**
++    Decide where to point the uc_stack.ss_sp field of our "context"
++    structure.  The configuration values CMK_CONTEXT_STACKBEGIN, 
++    CMK_CONTEXT_STACKEND, and CMK_CONTEXT_STACKMIDDLE determine where to
++    point ss_sp: to the beginning, end, and middle of the stack buffer
++    respectively.  The default, used by most machines, is CMK_CONTEXT_STACKBEGIN.
++    */
  #if CMK_THREADS_USE_JCONTEXT /* Jcontext is always STACKBEGIN */
    ss_sp = stack;
  #elif CMK_CONTEXT_STACKEND /* ss_sp should point to *end* of buffer */
  #else /* CMK_CONTEXT_STACKBEGIN, the usual case  */
    ss_sp = stack;
  #endif
--  
++
    result->context.uc_stack.ss_sp = STP_STKALIGN(ss_sp,sizeof(char *)*8);
    result->context.uc_stack.ss_size = ptrDiffLen(result->context.uc_stack.ss_sp,ss_end);
    result->context.uc_stack.ss_flags = 0;
    result->context.uc_link = 0;
--  
++
    CthAliasEnable(B(result)); /* Change to new thread's stack while building context */
    errno = 0;
  #if CMK_THREADS_USE_CONTEXT
    CthAliasEnable(B(CthCpvAccess(CthCurrent)));
  
  #if CMK_THREADS_BUILD_TLS
--  allocNewTLSSeg(&B(result)->tlsseg);
++  allocNewTLSSeg(&B(result)->tlsseg, result);
  #endif
  
    return result;  
@@@ -1728,20 -1726,20 +1728,20 @@@ CthThread CthPup(pup_er p, CthThread t
  {
    int flag;
    if (pup_isUnpacking(p)) {
--        t=(CthThread)malloc(sizeof(struct CthThreadStruct));
--        _MEMCHECK(t);
--        CthThreadInit(t);
++    t=(CthThread)malloc(sizeof(struct CthThreadStruct));
++    _MEMCHECK(t);
++    CthThreadInit(t);
    }
    CthPupBase(p,&t->base,1);
--  
++
    /*Pup the processor context as bytes-- this is not guarenteed to work!*/
    /* so far, context and context-memoryalias works for IA64, not ia32 */
    /* so far, uJcontext and context-memoryalias works for IA32, not ia64 */
    pup_bytes(p,&t->context,sizeof(t->context));
  #if !CMK_THREADS_USE_JCONTEXT && CMK_CONTEXT_FPU_POINTER
  #if ! CMK_CONTEXT_FPU_POINTER_UCREGS
--    /* context is not portable for ia32 due to pointer in uc_mcontext.fpregs,
--       pup it separately */
++  /* context is not portable for ia32 due to pointer in uc_mcontext.fpregs,
++     pup it separately */
    if (!pup_isUnpacking(p)) flag = t->context.uc_mcontext.fpregs != NULL;
    pup_int(p,&flag);
    if (flag) {
  #endif
  #endif
  #if !CMK_THREADS_USE_JCONTEXT && CMK_CONTEXT_V_REGS
--    /* linux-ppc  64 bit */
++  /* linux-ppc  64 bit */
    if (pup_isUnpacking(p)) {
--      t->context.uc_mcontext.v_regs = malloc(sizeof(vrregset_t));
++    t->context.uc_mcontext.v_regs = malloc(sizeof(vrregset_t));
    }
    pup_bytes(p,t->context.uc_mcontext.v_regs,sizeof(vrregset_t));
  #endif
    if (pup_isUnpacking(p)) {
--      t->context.uc_link = 0;
++    t->context.uc_link = 0;
    }
    if (pup_isDeleting(p)) {
--        CthFree(t);
--        return 0;
++    CthFree(t);
++    return 0;
    }
    return t;
  }
  
  #else 
  /***************************************************************
--Basic qthreads implementation. 
++  Basic qthreads implementation. 
  
--These threads can also add a "protection block" of
--inaccessible memory to detect stack overflows, which
--would otherwise just trash the heap.
++  These threads can also add a "protection block" of
++  inaccessible memory to detect stack overflows, which
++  would otherwise just trash the heap.
  
--(7/13/2001 creation times on 300MHz AMD K6-3 x86, Linux 2.2.18:
--Qt setjmp, without stackprotect: 18.5 us
--Qt i386, without stackprotect: 17.9 us
--Qt setjmp, with stackprotect: 68.6 us
--)
++  (7/13/2001 creation times on 300MHz AMD K6-3 x86, Linux 2.2.18:
++  Qt setjmp, without stackprotect: 18.5 us
++  Qt i386, without stackprotect: 17.9 us
++  Qt setjmp, with stackprotect: 68.6 us
++  )
  
--Written by Josh Yelon around 1995
--*/
++  Written by Josh Yelon around 1995
++  */
  
  #if !CMK_ERROR_CHECKING || (!CMK_MEMORY_PROTECTABLE)
  #  define CMK_STACKPROTECT 0
  #else
  #  define CMK_STACKPROTECT 1
  
--  extern void setProtection(char*, char*, int, int);
++extern void setProtection(char*, char*, int, int);
  #  include "sys/mman.h"
  #  define CthMemAlign(x,n) memalign((x),(n))
  #  define CthMemoryProtect(m,p,l) mprotect(p,l,PROT_NONE);setProtection((char*)m,p,l,1);
@@@ -1829,7 -1827,7 +1829,7 @@@ static CthThread CthThreadInit(void
    CthThreadBaseInit(&ret->base);
    ret->protect = 0;
    ret->protlen = 0;
--  
++
    return ret;
  }
  
@@@ -1884,7 -1882,7 +1884,7 @@@ void CthResume(CthThread) __attribute__
  #endif
  
  void CthResume(t)
--CthThread t;
++  CthThread t;
  {
    CthThread tc = CthCpvAccess(CthCurrent);
    if (t == tc) return;
    } else {
      QT_BLOCK((qt_helper_t*)CthBlockHelp, tc, 0, t->stackp);
    }
--/*This check will mistakenly fail if the thread migrates (changing tc)
--  if (tc!=CthCpvAccess(CthCurrent)) { CmiAbort("Stack corrupted?\n"); }
--*/
++  /*This check will mistakenly fail if the thread migrates (changing tc)
++    if (tc!=CthCpvAccess(CthCurrent)) { CmiAbort("Stack corrupted?\n"); }
++    */
  }
  
  static void CthOnly(void *arg, void *vt, qt_userf_t fn)
@@@ -1917,12 -1915,12 +1917,12 @@@ static CthThread CthCreateInner(CthVoid
    result=CthThreadInit();
    if (doProtect) 
    { /*Can only protect on a page boundary-- allocate an extra page and align stack*/
--        if (size==0) size=CthCpvAccess(_defaultStackSize);
--        size = (size+(CMK_MEMORY_PAGESIZE*2)-1) & ~(CMK_MEMORY_PAGESIZE-1);
--        stack = (qt_t*)CthMemAlign(CMK_MEMORY_PAGESIZE, size);
--          B(result)->stack = stack;
++    if (size==0) size=CthCpvAccess(_defaultStackSize);
++    size = (size+(CMK_MEMORY_PAGESIZE*2)-1) & ~(CMK_MEMORY_PAGESIZE-1);
++    stack = (qt_t*)CthMemAlign(CMK_MEMORY_PAGESIZE, size);
++    B(result)->stack = stack;
    } else
--        stack=CthAllocateStack(&result->base,&size,Migratable);
++    stack=CthAllocateStack(&result->base,&size,Migratable);
    CthAliasEnable(B(result)); /* Change to new thread's stack while setting args */
    stackbase = QT_SP(stack, size);
    stackp = QT_ARGS(stackbase, arg, result, (qt_userf_t *)fn, CthOnly);
    result->stackp = stackp;
    if (doProtect) {
  #ifdef QT_GROW_UP
--  /*Stack grows up-- protect highest page of stack*/
++    /*Stack grows up-- protect highest page of stack*/
      result->protect = ((char*)stack) + size - CMK_MEMORY_PAGESIZE;
  #else
--  /*Stack grows down-- protect lowest page in stack*/
++    /*Stack grows down-- protect lowest page in stack*/
      result->protect = ((char*)stack);
  #endif
      result->protlen = CMK_MEMORY_PAGESIZE;
@@@ -1966,29 -1964,29 +1966,29 @@@ int CthMigratable(
  CthThread CthPup(pup_er p, CthThread t)
  {
    if (pup_isUnpacking(p)) {
--        t=CthThreadInit();
++    t=CthThreadInit();
    }
  #if CMK_THREADS_ALIAS_STACK
    CthPupBase(p,&t->base,0);
  #else
    CthPupBase(p,&t->base,1);
  #endif
--  
++
    /*Pup the stack pointer as bytes-- this works because stack is migratable*/
    pup_bytes(p,&t->stackp,sizeof(t->stackp));
  
    /*Don't worry about stack protection on migration*/  
  
    if (pup_isDeleting(p)) {
--        CthFree(t);
--        return 0;
++    CthFree(t);
++    return 0;
    }
    return t;
  }
  
  /* Functions that help debugging of out-of-core emulation in BigSim */
  void CthPrintThdStack(CthThread t){
--    CmiPrintf("thread=%p, base stack=%p, stack pointer=%p\n", t, t->base.stack, t->stackp);
++  CmiPrintf("thread=%p, base stack=%p, stack pointer=%p\n", t, t->base.stack, t->stackp);
  }
  #endif
  
@@@ -2026,6 -2024,6 +2026,6 @@@ void CthTraceResume(CthThread t
  
  /* Functions that help debugging of out-of-core emulation in BigSim */
  void CthPrintThdMagic(CthThread t){
--    CmiPrintf("CthThread[%p]'s magic: %x\n", t, t->base.magic);
++  CmiPrintf("CthThread[%p]'s magic: %x\n", t, t->base.magic);
  }
  
index 61bf2cb261ff1e44211f5719a5ca58a2eed80942,61bf2cb261ff1e44211f5719a5ca58a2eed80942..37a53f329e94f172f875fe654ca80953fb75e14d
@@@ -65,7 -65,7 +65,7 @@@ ArmciVirtualProcessor::ArmciVirtualProc
    thisProxy = this;
    tcharmClientInit();
    thread->semaPut(ARMCI_TCHARM_SEMAID,this);
--  memBlock = CmiIsomallocBlockListNew();
++  memBlock = CmiIsomallocBlockListNew(NULL);
    thisProxy = CProxy_ArmciVirtualProcessor(thisArrayID);
    addressReply = NULL;
    // Save ourselves for the waiting ARMCI_Init
@@@ -561,7 -561,7 +561,7 @@@ void ArmciVirtualProcessor::notify_wait
  
  void ArmciVirtualProcessor::pup(PUP::er &p) {
    TCharmClient1D::pup(p);
--  CmiIsomallocBlockListPup(&p, &memBlock);
++  CmiIsomallocBlockListPup(&p, &memBlock,NULL);
    p|thisProxy;
    p|hdlList;
    p|noteList;
index 48c5f826d3283ce8c5f8c20cc49f927485ca59ee,48c5f826d3283ce8c5f8c20cc49f927485ca59ee..d6c5b70f51d0d5536f9084b29cbb486269cdb874
@@@ -189,9 -189,9 +189,9 @@@ TCharm::TCharm(TCharmInitMsg *initMsg_
    threadInfo.tProxy=CProxy_TCharm(thisArrayID);
    threadInfo.thisElement=thisIndex;
    threadInfo.numElements=initMsg->numElements;
--  if (CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC))
--      heapBlocks=CmiIsomallocBlockListNew();
--  else
++  if (CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC)) {
++      heapBlocks=CmiIsomallocBlockListNew(tid);
++  else
        heapBlocks=0;
    nUd=0;
    usesAtSync=CmiTrue;
@@@ -315,6 -315,6 +315,7 @@@ void TCharm::pup(PUP::er &p) 
  // Pup our thread and related data
  void TCharm::pupThread(PUP::er &pc) {
      pup_er p=(pup_er)&pc;
++    CthThread savedtid = tid;
      checkPupMismatch(pc,5138,"before TCHARM thread");
      tid = CthPup(p, tid);
      if (pc.isUnpacking()) {
  #endif
      }
      if (CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC))
--      CmiIsomallocBlockListPup(p,&heapBlocks);
++      CmiIsomallocBlockListPup(p,&heapBlocks,savedtid);
      threadGlobals=CtgPup(p,threadGlobals);
      checkPupMismatch(pc,5139,"after TCHARM thread");
  }
index c516df0638d9cb70a7b03d006b73868b6791dbbb,c516df0638d9cb70a7b03d006b73868b6791dbbb..34b44b0f6bdf5d64b706945fa656f702da555140
@@@ -38,14 -38,14 +38,15 @@@ Phdr* getTLSPhdrEntry() 
    return NULL;
  }
  
--void allocNewTLSSeg(tlsseg_t* t) {
++void allocNewTLSSeg(tlsseg_t* t, CthThread th) {
    Phdr* phdr;
  
    phdr = getTLSPhdrEntry();
    if (phdr != NULL) {
      t->size = phdr->p_memsz;
      t->align = phdr->p_align;
--    t->memseg = (Addr)CmiIsomallocAlign(t->align, t->size);
++    t->memseg = (Addr)CmiIsomallocAlign(t->align, t->size, th);
++//    t->memseg = (Addr)CmiIsomallocAlign(t->align, t->size);
      //t->memseg = memalign(t->align, t->size);
      memset((void*)t->memseg, 0, t->size);
      memcpy((void*)t->memseg, (void*) (phdr->p_vaddr), (size_t)(phdr->p_filesz));