Adding limit to mempool expansion
authorNikhil Jain <nikhil@illinois.edu>
Mon, 27 Feb 2012 22:17:14 +0000 (14:17 -0800)
committerNikhil Jain <nikhil@illinois.edu>
Mon, 27 Feb 2012 22:17:14 +0000 (14:17 -0800)
src/arch/gemini_gni/machine.c
src/arch/util/mempool.c
src/arch/util/mempool.h
src/conv-core/isomalloc.c

index a1092f9864603175fa0750f9f52018073de5f110..41a3718dbaaaf0cd249be32333e2dfd8785f5725 100644 (file)
@@ -2579,7 +2579,7 @@ void free_mempool_block(void *ptr, gni_mem_handle_t mem_hndl)
 void LrtsPreCommonInit(int everReturn){
 #if USE_LRTS_MEMPOOL
     CpvInitialize(mempool_type*, mempool);
-    CpvAccess(mempool) = mempool_init(_mempool_size, alloc_mempool_block, free_mempool_block);
+    CpvAccess(mempool) = mempool_init(_mempool_size, alloc_mempool_block, free_mempool_block, 0);
     MACHSTATE2(8, "mempool_init %d %p\n", CmiMyRank(), CpvAccess(mempool)) ; 
 #endif
 }
index bb10c9da3fe812729b1bd4ec5c93201a799f5fe2..18afdc2f2cce4e6f6ef84b1bcc6cd00b5e54581e 100644 (file)
@@ -169,7 +169,39 @@ int checkblock(mempool_type *mptr,block_header *current,int power)
   }
 }
 
-mempool_type *mempool_init(size_t pool_size, mempool_newblockfn allocfn, mempool_freeblock freefn)
+void removeblocks(mempool_type *mptr)
+{
+  block_header *current,*prev,*tofree,*tail;
+  mempool_freeblock freefn = mptr->freeblockfn;
+
+  if(mptr == NULL)
+    return;
+
+  tail = (block_header*)((char*)mptr+mptr->block_tail);
+  current = prev = &(mptr->block_head);
+  current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
+
+  while(current != NULL) {
+    if(current->used <= 0) {
+      tofree = current;
+      current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
+      if(tail == tofree) {
+        mptr->block_tail = tofree->block_prev;
+      }
+      prev->block_next = tofree->block_next;
+      if(current != NULL) {
+        current->block_prev = tofree->block_prev;
+      }
+      mptr->size -= tofree->size;
+      freefn(tofree, tofree->mem_hndl);
+    } else {
+      prev = current;
+      current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
+    }
+  }
+}
+
+mempool_type *mempool_init(size_t pool_size, mempool_newblockfn allocfn, mempool_freeblock freefn, size_t limit)
 {
   int i,power;
   size_t end,left,prev,next;
@@ -182,12 +214,16 @@ mempool_type *mempool_init(size_t pool_size, mempool_newblockfn allocfn, mempool
   mptr->newblockfn = allocfn;
   mptr->freeblockfn = freefn;
   mptr->block_tail = 0;
+  mptr->limit = limit;
+  mptr->size = pool_size;
 #if CMK_USE_MEMPOOL_ISOMALLOC || (CMK_SMP && CMK_CONVERSE_GEMINI_UGNI)
   mptr->mempoolLock = CmiCreateLock();
 #endif
   mptr->block_head.mptr = pool;
   mptr->block_head.mem_hndl = mem_hndl;
   mptr->block_head.size = pool_size;
+  mptr->block_head.used = 0;
+  mptr->block_head.block_prev = 0;
   mptr->block_head.block_next = 0;
 #if CMK_CONVERSE_GEMINI_UGNI
   mptr->block_head.msgs_in_send= 0;
@@ -252,8 +288,12 @@ void*  mempool_malloc(mempool_type *mptr, int size, int expand)
       if (!expand) return NULL;
 
 #if MEMPOOL_DEBUG
-      CmiPrintf("Expanding\n");
+      CmiPrintf("Expanding size %lld limit %lld\n",mptr->size,mptr->limit);
 #endif
+      //free blocks which are not being used
+      if((mptr->size > mptr->limit) && (mptr->limit > 0)) {
+        removeblocks(mptr);
+      }
 
       tail = (block_header*)((char*)mptr+mptr->block_tail);
       expand_size = 2*bestfit_size + sizeof(block_header); 
@@ -263,12 +303,15 @@ void*  mempool_malloc(mempool_type *mptr, int size, int expand)
         return NULL;
       }
 
+      mptr->size += expand_size;
       current = (block_header*)pool; 
       tail->block_next = ((char*)current-(char*)mptr);
+      current->block_prev = mptr->block_tail;
       mptr->block_tail = tail->block_next;
 
       current->mptr = mptr;
       current->mem_hndl = mem_hndl;
+      current->used = 0;
       current->size = expand_size;
       current->block_next = 0;
 #if CMK_CONVERSE_GEMINI_UGNI
@@ -294,6 +337,7 @@ void*  mempool_malloc(mempool_type *mptr, int size, int expand)
       }
 
       head_free->block_ptr = current;
+      current->used += power;
 #if CMK_USE_MEMPOOL_ISOMALLOC || (CMK_SMP && CMK_CONVERSE_GEMINI_UGNI)
       CmiUnlock(mptr->mempoolLock);
 #endif
@@ -332,25 +376,11 @@ void mempool_free(mempool_type *mptr, void *ptr_free)
               ((char*)ptr_free - (char*)mptr - sizeof(used_header)));
 #endif
 
-    //find which block this slot belonged to, can be done
-    //by maintaining extra 8 bytes in slot_header but I am
-    //currently doing it by linear search for gemini
-    block_head = &mptr->block_head;
-    while(block_head != NULL) {
-      if((size_t)ptr_free >= (size_t)(block_head)
-        && (size_t)ptr_free < (size_t)((char*)block_head
-        + block_head->size)) {
-        break;
-      }
-      block_head = block_head->block_next?(block_header *)((char*)mptr+block_head->block_next):NULL;
-    }
-    if(block_head==NULL) {
-      CmiPrintf("[%d] Mempool-Free request pointer was not in mempool range %lld\n",CthSelf(),ptr_free);
-      return;
-    }
 
     to_free = (slot_header *)((char*)ptr_free - sizeof(used_header));
     to_free->status = 1;
+    block_head = to_free->block_ptr;
+    block_head->used -= to_free->size;
 
     //find the neighborhood of to_free which is also free and
     //can be merged to get larger free slots 
index d82848f082bd52d1ad9157ce6c1fb4a06ba271ec..b8c94c9911196267b7ad12c0b5014d64f70eb568 100644 (file)
@@ -27,7 +27,7 @@ struct mempool_type;
 typedef struct slot_header_
 {
   struct block_header  *block_ptr;     // block_header
-  int                  size,status;  //status is 1 for free, 0 for used
+  int                          size,status;  //status is 1 for free, 0 for used
   size_t               gprev,gnext;  //global slot list within a block
   size_t               prev,next;    //link list for freelists slots
   size_t                padding;      // fix for 32 bit machines
@@ -47,8 +47,8 @@ typedef used_header mempool_header;
 typedef struct block_header
 {
     mem_handle_t        mem_hndl;
-    size_t              size;
-    size_t              block_next;           // offset to next memblock
+    size_t              size, used;
+    size_t              block_prev,block_next;   // offset to next memblock
     size_t              freelists[cutOffNum];
     struct mempool_type  *mptr;               // mempool_type
     size_t              padding;              // fix for 32 bit machines
@@ -65,12 +65,14 @@ typedef struct mempool_type
   mempool_newblockfn     newblockfn;
   mempool_freeblock      freeblockfn;
   size_t                 block_tail;
+  size_t                 limit;
+  size_t                 size;
 #if CMK_USE_MEMPOOL_ISOMALLOC || (CMK_SMP && CMK_CONVERSE_GEMINI_UGNI)
   CmiNodeLock           mempoolLock;
 #endif
 } mempool_type;
 
-mempool_type *mempool_init(size_t pool_size, mempool_newblockfn newfn, mempool_freeblock freefn);
+mempool_type *mempool_init(size_t pool_size, mempool_newblockfn newfn, mempool_freeblock freefn, size_t limit);
 void  mempool_destroy(mempool_type *mptr);
 void*  mempool_malloc(mempool_type *mptr, int size, int expand);
 void mempool_free(mempool_type *mptr, void *ptr_free);
index 16b18ef40ab6bdf3dd41a69968c198474df8e88a..042b8761ba31bcd9ffb414a848fecb957e921627 100644 (file)
@@ -2307,7 +2307,7 @@ void *CmiIsomalloc(int size, CthThread tid)
 #if ISOMALLOC_DEBUG
       printf("Init Mempool in %d for %d\n",CthSelf(), tid);
 #endif
-      CtvAccessOther(tid,threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn);
+      CtvAccessOther(tid,threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn,0);
     }
     blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccessOther(tid,threadpool),size+sizeof(CmiIsomallocBlock),1);
   } else {
@@ -2315,7 +2315,7 @@ void *CmiIsomalloc(int size, CthThread tid)
 #if ISOMALLOC_DEBUG
       printf("Init Mempool in %d\n",CthSelf());
 #endif
-      CtvAccess(threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn);
+      CtvAccess(threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn,0);
     }
     blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccess(threadpool),size+sizeof(CmiIsomallocBlock),1);
   }