Fixing some bugs, not perfect yet
authorNikhil Jain <nikhil@illinois.edu>
Tue, 15 Nov 2011 11:00:44 +0000 (05:00 -0600)
committerNikhil Jain <nikhil@illinois.edu>
Tue, 15 Nov 2011 11:00:44 +0000 (05:00 -0600)
src/arch/util/mempool.c
src/arch/util/mempool.h
src/conv-core/isomalloc.c

index 6974963dd29692859a48c22bc8fe7cc4ac771e0c..bec086b37cafda9493afd95d5c2ffc65b57f8609 100644 (file)
@@ -5,14 +5,11 @@ Memory pool implementation , It is only good for Charm++ usage. The first 64 byt
 
 Written by Yanhua Sun 08-27-2011
 Generalized by Gengbin Zheng  10/5/2011
-
+Heavily modified by Nikhil Jain
 */
 
 #define MEMPOOL_DEBUG   0
 
-#define POOLS_NUM       2
-#define MAX_INT        2147483647
-
 #include "converse.h"
 
 #include <stdio.h>
@@ -23,289 +20,410 @@ Generalized by Gengbin Zheng  10/5/2011
 #endif
 
 #include "mempool.h"
+int cutOffPoints[] = {64,128,256,512,1024,2048,4096, 8192,16384,32768,
+                      65536,131072,262144,524288,1048576,2097152,4194304,
+                      8388608,16777216,33554432,67108864,134217728,268435456,
+                      536870912};
 
 
-mempool_type *mempool_init(size_t pool_size, mempool_newblockfn allocfn, mempool_freeblock freefn)
+inline int which_pow2(size_t size)
 {
-    mempool_type *mptr;
-    mempool_header *header;
-    mem_handle_t  mem_hndl;
+  int i;
+  for(i=0; i<cutOffNum; i++) {
+    if(size <= cutOffPoints[i]) {
+      return i;
+    }
+  }
+  return i;
+}
 
-    void *pool = allocfn(&pool_size, &mem_hndl, 0);
-    mptr = (mempool_type*)pool;
-    mptr->newblockfn = allocfn;
-    mptr->freeblockfn = freefn;
-#if CMK_SMP
-    mptr->mempoolLock = CmiCreateLock();
-#endif
-    mptr->mempools_head.mempool_ptr = pool;
-    mptr->mempools_head.mem_hndl = mem_hndl;
-    mptr->mempools_head.size = pool_size;
-    mptr->mempools_head.memblock_next = 0;
-    header = (mempool_header *) ((char*)pool+sizeof(mempool_type));
-    mptr->freelist_head = sizeof(mempool_type);
-    mptr->memblock_tail = 0;
+//method to initialize the freelists of a newly allocated block
+inline void fillblock(mempool_type *mptr,block_header *block_head,int pool_size,int expansion) 
+{
+  int         i,power;
+  size_t      loc,left,prev;
+  slot_header *head;
+  void        *pool;
+
+  for(i=0; i<cutOffNum;i++) {
+    block_head->freelists[i] = 0;
+  }
+
+  pool = block_head->mempool_ptr;
+  if(expansion) {
+    left = pool_size-sizeof(block_header);
+    loc = (char*)pool+sizeof(block_header)-(char*)mptr;
+  } else {
+    left = pool_size-sizeof(mempool_type);
+    loc = (char*)pool+sizeof(mempool_type)-(char*)mptr;
+  }
+  power = which_pow2(left);
+  if(left < cutOffPoints[power]) {
+    power--;
+  }
 #if MEMPOOL_DEBUG
-    printf("[%d] pool: %p  free: %p\n", myrank, pool, header);
+  CmiPrintf("Left is %d, Max power obtained is %d\n",left,power);
 #endif
-    header->size = pool_size-sizeof(mempool_type)-sizeof(mempool_header);
-    header->mem_hndl = mem_hndl;
-    header->next_free = 0;
-    return mptr;
+
+  for(i=power; i>=0; i--) {
+    if(left>=cutOffPoints[i]) {
+      block_head->freelists[i] = loc;
+      loc += cutOffPoints[i];
+      left -= cutOffPoints[i];
+    }
+  }
+
+  prev = 0;
+  for(i=power; i>=0; i--) {
+    if(block_head->freelists[i]) {
+      head = (slot_header*)((char*)mptr+block_head->freelists[i]);
+      head->size = cutOffPoints[i];
+      head->status = 1;
+#if CMK_CONVERSE_GEMINI_UGNI
+      head->mem_hndl = block_head->mem_hndl;
+#endif
+      head->prev = head->next = 0;
+      head->gprev = prev;
+      if(i!=power) {
+        ((slot_header*)((char*)mptr+prev))->gnext = block_head->freelists[i];
+      }
+      prev = block_head->freelists[i];
+    }
+  }
+  head->gnext = 0;
 }
 
-void mempool_destroy(mempool_type *mptr)
+//method to check if a request can be met by this block
+//if yes, alter the block free list appropiately 
+int checkblock(mempool_type *mptr,block_header *current,int power)
 {
-    mempool_block *current, *mempools_head;
-    mempool_freeblock   freefn = mptr->freeblockfn;
-
-    current = mempools_head = &(mptr->mempools_head);
+  int         i,powiter;
+  size_t      prev,loc,gnext;
+  slot_header *head,*head_free,*head_move,*head_next;
+  head_free = current->freelists[power]?(slot_header*)((char*)mptr+current->freelists[power]):NULL;
+
+  //if the freelist of required size is empty, check if free
+  //list of some larger size is non-empty and break a slot from it
+  powiter = power+1;
+  while(head_free==NULL && powiter<cutOffNum) {
+    if(current->freelists[powiter]) {
+      head_move = (slot_header*)((char*)mptr+current->freelists[powiter]);
+      gnext = head_move->gnext;
+      loc = current->freelists[powiter];
+      current->freelists[powiter] = head_move->next;
+      current->freelists[power] = loc;
+      //we get 2 entries for smallest size required
+      loc = loc+cutOffPoints[power];
+      for(i=power+1; i<powiter; i++) { 
+        loc = loc+cutOffPoints[i-1];
+        current->freelists[i] = loc;
+      }
 
-    while(mempools_head!= NULL)
-    {
-#if MEMPOOL_DEBUG
-        printf("[%d] free mempool:%p\n", CmiMyPe(), mempools_head->mempool_ptr);
+      head_move->size = cutOffPoints[power];
+      prev = current->freelists[power];
+      head_move->next = prev+cutOffPoints[power]; 
+      head = (slot_header*)((char*)head_move+cutOffPoints[power]);
+      for(i=power; i<powiter; i++) {
+        if(i!=power) {
+          head = (slot_header*)((char*)head+cutOffPoints[i-1]);
+        }
+        head->size = cutOffPoints[i];
+        head->status = 1;
+#if CMK_CONVERSE_GEMINI_UGNI
+       head->mem_hndl = current->mem_hndl;
 #endif
-        current=mempools_head;
-        mempools_head = mempools_head->memblock_next?(mempool_block *)((char*)mptr+mempools_head->memblock_next):NULL;
-        freefn(current->mempool_ptr, current->mem_hndl);
+        head->prev = head->next = 0;
+        head->gprev = prev;
+        ((slot_header*)((char*)mptr+prev))->gnext = (char*)head-(char*)mptr;
+        if(i!=power) {
+          prev = prev+cutOffPoints[i-1];
+        } else {
+          prev = prev+cutOffPoints[i];
+        }
+      }
+      ((slot_header*)((char*)head_move+cutOffPoints[power]))->prev = 
+      current->freelists[power];
+      head->gnext = gnext;
+      if(gnext!= 0) {
+        ((slot_header*)((char*)mptr+gnext))->gprev = prev;
+      }
+      if(current->freelists[powiter]) {
+        head_next = (slot_header*)((char*)mptr+current->freelists[powiter]);
+        head_next->prev = 0;
+      }
+      head_free = (slot_header*)((char*)mptr+current->freelists[power]);
     }
+    powiter++;
+  }
+  if(head_free == NULL) {
+    return 0;
+  } else {
+    return 1;
+  }
 }
 
-// append size before the real memory buffer
+mempool_type *mempool_init(size_t pool_size, mempool_newblockfn allocfn, mempool_freeblock freefn)
+{
+  int i,power;
+  size_t end,left,prev,next;
+  mempool_type *mptr;
+  slot_header *head;
+  mem_handle_t  mem_hndl;
+
+  void *pool = allocfn(&pool_size, &mem_hndl, 0);
+  mptr = (mempool_type*)pool;
+  mptr->newblockfn = allocfn;
+  mptr->freeblockfn = freefn;
+  mptr->block_tail = 0;
+#if CMK_SMP && CMK_CONVERSE_GEMINI_UGNI
+  mptr->mempoolLock = CmiCreateLock();
+#endif
+  mptr->block_head.mempool_ptr = pool;
+  mptr->block_head.mem_hndl = mem_hndl;
+  mptr->block_head.size = pool_size;
+  mptr->block_head.block_next = 0;
+
+  fillblock(mptr,&mptr->block_head,pool_size,0);
+  return mptr;
+}
+
+void mempool_destroy(mempool_type *mptr)
+{
+  block_header *current,*tofree;
+  mempool_freeblock   freefn = mptr->freeblockfn;
+
+  current = tofree = &(mptr->block_head);
+
+  while(current != NULL) {
+    tofree = current;
+    current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
+    freefn(tofree->mempool_ptr, tofree->mem_hndl);
+  }
+}
+
+// append slot_header size before the real memory buffer
 void*  mempool_malloc(mempool_type *mptr, int size, int expand)
 {
-    int     bestfit_size = MAX_INT; //most close size 
-    size_t    *freelist_head = &mptr->freelist_head;
-    mempool_header *freelist_head_ptr; 
-    mempool_header *current, *previous, *bestfit, *bestfit_previous;
+    void          *pool;
+    int           i;
+    size_t        expand_size;
+    int           power, bestfit_size; //most close power of cutoffpoint 
+    block_header  *current,*tail;
+    slot_header   *head_free,*head_next;
+    mem_handle_t  mem_hndl;
 
-#if CMK_SMP
+#if CMK_SMP && CMK_CONVERSE_GEMINI_UGNI
     CmiLock(mptr->mempoolLock);
 #endif
-    freelist_head_ptr = mptr->freelist_head?(mempool_header*)((char*)mptr+mptr->freelist_head):NULL;
-    current = freelist_head_ptr;
-    previous = NULL;
-    bestfit = NULL;
-    bestfit_previous = NULL;
-
-#if  MEMPOOL_DEBUG
-    CmiPrintf("[%d] request malloc from pool: %p  free_head: %p %d for size %d, \n", CmiMyPe(), mptr, freelist_head_ptr, mptr->freelist_head, size);
-#endif
 
-    size += sizeof(mempool_header);
-
-#if 1
-    while(current!= NULL)     /* best fit */
-    {
-#if  MEMPOOL_DEBUG
-        CmiPrintf("[%d] current=%p size:%d \n", CmiMyPe(), current, current->size);
-#endif
-        if(current->size >= size && current->size < bestfit_size)
-        {
-            bestfit_size = current->size;
-            bestfit = current;
-            bestfit_previous = previous;
-        }
-        previous = current;
-        current = current->next_free?(mempool_header*)((char*)mptr + current->next_free):NULL;
-    }
-#else
-    while(current!= NULL)             /*  first fit */
-    {
-#if  MEMPOOL_DEBUG
-        CmiPrintf("[%d] current=%p size:%d ->%p \n", CmiMyPe(), current, current->size, (char*)current+current->size);
+    bestfit_size = size + sizeof(used_header);
+    power = which_pow2(bestfit_size);
+    bestfit_size = cutOffPoints[power];
+    //if(CmiMyPe() == 0)
+    //  printf("malloc for %lld, %lld, %lld\n",size,bestfit_size,power);
+#if MEMPOOL_DEBUG
+    CmiPrintf("Request size is %d, power value is %d, size is %d\n",size,power,cutOffPoints[power]);
 #endif
-        CmiAssert(current->size != 0);
-        if(current->size >= size)
-        {
-            bestfit_size = current->size;
-            bestfit = current;
-            bestfit_previous = previous;
-            break;
-        }
-        previous = current;
-        current = current->next_free?(mempool_header*)((char*)mptr + current->next_free):NULL;
+
+    head_free = NULL;
+    current = &mptr->block_head;
+    while(current != NULL) {
+     if(checkblock(mptr,current,power)) {
+        head_free = current->freelists[power]?(slot_header*)((char*)mptr+current->freelists[power]):NULL;
+        break;
+      } else {
+        current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
+      }
     }
-#endif
 
-    if(bestfit == NULL)
-    {
-        void *pool;
-        mempool_block   *expand_pool, *memblock_tail;
-        size_t   expand_size;
-        mem_handle_t  mem_hndl;
-
-        if (!expand) return NULL;
-
-         /* set minimum size, newblockfn checks against the default size */
-        expand_size = size + sizeof(mempool_block); 
-        pool = mptr->newblockfn(&expand_size, &mem_hndl, 1);
-        expand_pool = (mempool_block*)pool;
-        expand_pool->mempool_ptr = pool;
-        expand_pool->mem_hndl = mem_hndl;
-        expand_pool->size = expand_size;
-        expand_pool->memblock_next = 0;
+    //no space in current blocks, get a new one
+    if(head_free==NULL) {
+      //if(CmiMyPe() == 0)
+       //printf("Will attempt to expand now\n");
+      if (!expand) return NULL;
+
 #if MEMPOOL_DEBUG
-        printf("[%d] No memory has such free empty chunck of %d. expanding %p with new size %ld\n", CmiMyPe(), size, expand_pool->mempool_ptr, expand_size);
-#endif
-         /* insert new block to memblock tail */
-        memblock_tail = (mempool_block*)((char*)mptr + mptr->memblock_tail);
-        memblock_tail->memblock_next = mptr->memblock_tail = (char*)expand_pool - (char*)mptr;
-
-        bestfit = (mempool_header*)((char*)expand_pool->mempool_ptr + sizeof(mempool_block));
-        bestfit_size = expand_size-sizeof(mempool_block);
-        bestfit->size = bestfit_size;
-        bestfit->mem_hndl = expand_pool->mem_hndl;
-        bestfit->next_free = 0;
-#if 1
-         /* insert bestfit to the sorted free list */
-        previous = NULL;
-        current = freelist_head_ptr;
-        while (current) 
-        {
-            if (current > bestfit) break;
-            previous = current;
-            current = current->next_free?(mempool_header*)((char *)mptr + current->next_free):NULL;
-        };
-        bestfit->next_free = current!=NULL? (char*)current-(char*)mptr:0;
-#else
-        CmiAssert(bestfit > previous);
-        previous->next_free = (char*)bestfit-(char*)mptr;
+      CmiPrintf("Expanding\n");
 #endif
-        bestfit_previous = previous;
-        if (previous == NULL) {
-           *freelist_head = (char*)bestfit - (char*)mptr;
-           freelist_head_ptr =  bestfit;
-        }
-        else
-           previous->next_free = (char*)bestfit-(char*)mptr;
-    }
 
-    bestfit->size = size;
-    if(bestfit_size > size + sizeof(mempool_header)) //deduct this entry 
-    {
-        mempool_header *ptr = (mempool_header *)((char*)bestfit + size);
-        ptr->size = bestfit_size - size;
-        ptr->mem_hndl = bestfit->mem_hndl;
-        ptr->next_free = bestfit->next_free;
-        if(bestfit == freelist_head_ptr)
-           *freelist_head = (char*)ptr - (char*)mptr;
-        if(bestfit_previous != NULL)
-           bestfit_previous->next_free = (char*)ptr - (char*)mptr;
-    }
-    else {  
-          //delete this free entry
-        if (bestfit_size > size) {
-           bestfit->size = bestfit_size;
-        }
-        if(bestfit == freelist_head_ptr)
-            *freelist_head = freelist_head_ptr->next_free;
-        else
-            bestfit_previous->next_free = bestfit->next_free;
+      tail = (block_header*)((char*)mptr+mptr->block_tail);
+      expand_size = 2*bestfit_size; 
+      pool = mptr->newblockfn(&expand_size, &mem_hndl, 1);
+      if(pool==NULL) {
+        CmiPrintf("Mempool-Did not get memory while expanding\n");
+        return NULL;
+      }
+
+      current = (block_header*)pool; 
+      tail->block_next = ((char*)current-(char*)mptr);
+      mptr->block_tail = tail->block_next;
+
+      current->mempool_ptr = pool;
+      current->mem_hndl = mem_hndl;
+      current->size = expand_size;
+      current->block_next = 0;
+
+      fillblock(mptr,current,expand_size,1);
+      if(checkblock(mptr,current,power)) {
+        head_free = current->freelists[power]?(slot_header*)((char*)mptr+current->freelists[power]):NULL;
+      } else {
+        CmiPrintf("Mempool-No free block after expansion, something is broken in mempool\n");
+       return NULL;
+      }
     }
-#if  MEMPOOL_DEBUG
-    printf("[%d] ++MALLOC served: %d, ptr:%p\n", CmiMyPe(), size, bestfit);
-printf("[%d] freelist_head in malloc  offset:%d free_head: %ld %ld %d %d\n", myrank, (char*)bestfit-(char*)mptr, *freelist_head, ((mempool_header*)((char*)mptr+*freelist_head))->next_free, bestfit_size, size);
-#endif
-    CmiAssert(*freelist_head >= 0);
 
-#if CMK_SMP
-    CmiUnlock(mptr->mempoolLock);
-    bestfit->pool_addr = mptr;
-#endif
+    if(head_free!=NULL) {
+      head_free->status = 0;
+      current->freelists[power] = head_free->next;
+      head_next = current->freelists[power]?(slot_header*)((char*)mptr+current->freelists[power]):NULL;
+      if(head_next != NULL) {
+        head_next->prev = 0;
+      }
 
-    return (char*)bestfit + sizeof(mempool_header);
+#if CMK_SMP && CMK_CONVERSE_GEMINI_UGNI
+      head_free->pool_addr = mptr;
+      CmiUnlock(mptr->mempoolLock);
+#endif
+      return (char*)head_free + sizeof(used_header);
+    }
+    
+    CmiPrintf("Mempool - Reached a location which I should never have reached\n");
+    return NULL;
 }
 
-#if CMK_SMP
+#if CMK_SMP && CMK_CONVERSE_GEMINI_UGNI
 void mempool_free_thread( void *ptr_free)
 {
-    mempool_header *to_free;
+    slot_header *to_free;
     mempool_type *mptr;
 
-    to_free = (mempool_header *)((char*)ptr_free - sizeof(mempool_header));
-    mptr = (mempool_type*)(to_free->pool_addr); 
+    to_free = (slot_header *)((char*)ptr_free - sizeof(used_header));
+    mptr = (mempool_type*)(to_free->pool_addr);
     CmiLock(mptr->mempoolLock);
-    mempool_free(mptr,  ptr_free); 
+    mempool_free(mptr,  ptr_free);
     CmiUnlock(mptr->mempoolLock);
 }
 #endif
 
-//sorted free_list and merge it if it become continous 
 void mempool_free(mempool_type *mptr, void *ptr_free)
 {
-    int i;
-    int merged = 0;
-    int free_size;
-    void *free_lastbytes_pos;
-    size_t    *freelist_head;
-    mempool_header    *freelist_head_ptr;
-    mempool_header    *current;
-    mempool_header *previous = NULL;
-    mempool_header *to_free;
-
-    to_free = (mempool_header *)((char*)ptr_free - sizeof(mempool_header));
-
-    freelist_head = &mptr->freelist_head;
-    freelist_head_ptr = mptr->freelist_head?(mempool_header*)((char*)mptr+mptr->freelist_head):NULL;
-    current = freelist_head_ptr;
-
-    free_size = to_free->size;
-    free_lastbytes_pos = (char*)to_free +free_size;
-
-#if  MEMPOOL_DEBUG
-    printf("[%d] INSIDE FREE ptr=%p, size=%d freehead=%p mutex: %p\n", CmiMyPe(), to_free, free_size, freelist_head, mptr->mutex);
-#endif
-    
-    while(current!= NULL && current < to_free )
-    {
-#if  MEMPOOL_DEBUG
-        CmiPrintf("[%d] previous=%p, current=%p size:%d %p\n", CmiMyPe(), previous, current, current->size, (char*)current+current->size);
+    int           i,size;
+    int           left,power;
+    size_t        prev,loc;
+    block_header  *block_head;
+    slot_header   *to_free, *first, *current;
+    slot_header   *used_next,*temp;
+
+#if MEMPOOL_DEBUG
+    CmiPrintf("Free request for %lld\n",
+              ((char*)ptr_free - (char*)mptr - sizeof(used_header)));
 #endif
-        previous = current;
-        current = current->next_free?(mempool_header*)((char*)mptr + current->next_free):NULL;
+
+    //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(1 && block_head != NULL) {
+      if((size_t)ptr_free >= (size_t)(block_head->mempool_ptr)
+        && (size_t)ptr_free < (size_t)((char*)block_head->mempool_ptr 
+        + block_head->size)) {
+        break;
+      }
+      block_head = block_head->block_next?(block_header *)((char*)mptr+block_head->block_next):NULL;
     }
-#if  MEMPOOL_DEBUG
-    if (current) CmiPrintf("[%d] previous=%p, current=%p size:%d %p\n", CmiMyPe(), previous, current, current->size, free_lastbytes_pos);
-#endif
-    //continue with previous free space 
-    if(previous!= NULL && (char*)previous+previous->size == (char*)to_free &&  memcmp(&previous->mem_hndl, &to_free->mem_hndl, sizeof(mem_handle_t))==0 )
-    {
-        previous->size +=  free_size;
-        merged = 1;
+    if(block_head==NULL) {
+      CmiPrintf("Mempool-Free request pointer was not in mempool range\n");
+      return;
+    }
+
+    to_free = (slot_header *)((char*)ptr_free - sizeof(used_header));
+    to_free->status = 1;
+
+    //find the neighborhood of to_free which is also free and
+    //can be merged to get larger free slots 
+    size = 0;
+    current = to_free;
+    while(current->status == 1) {
+      size += current->size;
+      first = current;
+      current = current->gprev?(slot_header*)((char*)mptr+current->gprev):NULL;
+      if(current == NULL)
+        break;
+    }
+
+    size -= to_free->size;
+    current = to_free;
+    while(current->status == 1) {
+      size += current->size;
+      current = current->gnext?(slot_header*)((char*)mptr+current->gnext):NULL;
+      if(current == NULL)
+        break;
     }
-    else if(current!= NULL && free_lastbytes_pos == current && memcmp(&current->mem_hndl, &to_free->mem_hndl, sizeof(mem_handle_t))==0)
-    {
-        to_free->size += current->size;
-        to_free->next_free = current->next_free;
-        current = to_free;
-        merged = 1;
-        if(previous == NULL)
-            *freelist_head = (char*)current - (char*)mptr;
-        else
-            previous->next_free = (char*)to_free - (char*)mptr;
+    used_next = current;
+
+    //remove the free slots in neighbor hood from their respective
+    //free lists
+    current = first;
+    while(current!=used_next) {
+      if(current!=to_free) {
+        power = which_pow2(current->size);
+        temp = current->prev?(slot_header*)((char*)mptr+current->prev):NULL;
+        if(temp!=NULL) {
+          temp->next = current->next;
+        } else {
+          block_head->freelists[power] = current->next;
+        }
+        temp = current->next?(slot_header*)((char*)mptr+current->next):NULL;
+        if(temp!=NULL) {
+          temp->prev = current->prev;
+        }
+      }
+      current = current->gnext?(slot_header*)((char*)mptr+current->gnext):NULL;
+    }
+
+    //now create the new free slots of as large a size as possible
+    power = which_pow2(size);
+    if(size < cutOffPoints[power]) {
+      power--;
     }
-    //continous, merge
-    if(merged) {
-       if (previous!= NULL && current!= NULL && (char*)previous + previous->size  == (char *)current && memcmp(&previous->mem_hndl, &current->mem_hndl, sizeof(mem_handle_t))==0)
-      {
-         previous->size += current->size;
-         previous->next_free = current->next_free;
+    left = size;
+
+    //if(CmiMyPe() == 0)
+    //  printf("free was for %lld, merging for %lld, power %lld\n",to_free->size,size,power);
+     loc = (char*)first - (char*)mptr;
+    for(i=power; i>=0; i--) {
+      if(left>=cutOffPoints[i]) {
+        current = (slot_header*)((char*)mptr+loc);
+        current->size = cutOffPoints[i];
+        current->status = 1;
+#if CMK_CONVERSE_GEMINI_UGNI
+       current->mem_hndl = block_head->mem_hndl;
+#endif
+        if(i!=power) {
+          current->gprev = prev;
+        }
+        current->gnext = loc + cutOffPoints[i];
+        current->prev = 0;
+        if(block_head->freelists[i] == 0) {
+          current->next = 0;
+        } else {
+          current->next = block_head->freelists[i];
+          temp = (slot_header*)((char*)mptr+block_head->freelists[i]);
+          temp->prev = loc;
+        }
+        block_head->freelists[i] = loc;
+        prev = loc;
+        loc += cutOffPoints[i];
+        left -= cutOffPoints[i];
       }
     }
-    else {
-          // no merge to previous, current, create new entry
-        to_free->next_free = current?(char*)current - (char*)mptr: 0;
-        if(previous == NULL)
-            *freelist_head = (char*)to_free - (char*)mptr;
-        else
-            previous->next_free = (char*)to_free - (char*)mptr;
+   if(used_next!=NULL) {
+      used_next->gprev = (char*)current - (char*)mptr;
+    } else {
+      current->gnext = 0;
     }
-#if  MEMPOOL_DEBUG
-    printf("[%d] Memory free done %p, freelist_head=%p\n", CmiMyPe(), to_free,  freelist_head);
+#if MEMPOOL_DEBUG
+    CmiPrintf("Free done\n");
 #endif
-
-    CmiAssert(*freelist_head >= 0);
 }
 
index 64f2faae03fc674b522dce52f4993db0a22a9129..1f24020e1b5db7b7fce74a976d0b4e7825d5b232 100644 (file)
@@ -14,39 +14,58 @@ typedef gni_mem_handle_t    mem_handle_t;
 typedef size_t    mem_handle_t;
 #endif
 
-// multiple mempool for different size allocation
-typedef struct mempool_block_t
-{
-    void                *mempool_ptr;
-    mem_handle_t    mem_hndl;
-    int                 size;
-    size_t              memblock_next;     // offset to next memblock
-} mempool_block;
+typedef void * (* mempool_newblockfn)(size_t *size, mem_handle_t *mem_hndl, int expand_flag);
+typedef void (* mempool_freeblock)(void *ptr, mem_handle_t mem_hndl);
 
+#define cutOffNum 24 
 
-typedef struct mempool_header
+//header of an free slot
+typedef struct slot_header_
 {
-#if CMK_SMP
-  void*             pool_addr;
+#if CMK_SMP && CMK_CONVERSE_GEMINI_UGNI
+  void*                        pool_addr;
 #endif
-  mem_handle_t  mem_hndl;
-  size_t            next_free;
-  int size;
-} mempool_header;
+#if CMK_CONVERSE_GEMINI_UGNI
+  mem_handle_t         mem_hndl;
+#endif
+  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 either freelists slots
+} slot_header;
 
-typedef void * (* mempool_newblockfn)(size_t *size, mem_handle_t *mem_hndl, int expand_flag);
-typedef void (* mempool_freeblock)(void *ptr, mem_handle_t mem_hndl);
+typedef struct used_header_
+{
+#if CMK_SMP && CMK_GEMINI_UGNI
+  void*                        pool_addr;
+#endif
+#if CMK_CONVERSE_GEMINI_UGNI
+  mem_handle_t         mem_hndl;
+#endif
+  int                  size,status;  //status is 1 for free, 0 for used
+  size_t               gprev,gnext;  //global slot list within a block
+} used_header;
+
+typedef used_header mempool_header;
+
+// multiple mempool for different size allocation
+typedef struct block_header_
+{
+    void                *mempool_ptr;
+    mem_handle_t        mem_hndl;
+    size_t              size;
+    size_t              block_next;     // offset to next memblock
+    size_t              freelists[cutOffNum];
+} block_header;
 
 // only at beginning of first block of mempool
 typedef struct mempool_type
 {
-  mempool_block      mempools_head;
+  block_header           block_head;
   mempool_newblockfn     newblockfn;
   mempool_freeblock      freeblockfn;
-  size_t          freelist_head;
-  size_t          memblock_tail;
-#if CMK_SMP
-  CmiNodeLock     mempoolLock;
+  size_t                 block_tail;
+#if CMK_SMP && CMK_CONVERSE_GEMINI_UGNI
+    CmiNodeLock                mempoolLock;
 #endif
 } mempool_type;
 
@@ -54,9 +73,10 @@ mempool_type *mempool_init(size_t pool_size, mempool_newblockfn newfn, mempool_f
 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);
-#if CMK_SMP
+#if CMK_SMP && CMK_CONVERSE_GEMINI_UGNI
 void mempool_free_thread(void *ptr_free);
 #endif
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
index 3cd7b7c411d56f0744900252cb2fbec7566a14b3..c4ede540c4e26313eeb8bcb628dcd5a12290ea3f 100644 (file)
@@ -1680,7 +1680,7 @@ void * isomallocfn (size_t *size, mem_handle_t *mem_hndl, int expand_flag)
 //free function to be used by mempool
 void isofreefn(void *ptr, mem_handle_t mem_hndl)
 {
-  call_munmap(ptr, ((mempool_block *)ptr)->size);
+  call_munmap(ptr, ((block_header *)ptr)->size);
 }
 #endif
 
@@ -2022,7 +2022,7 @@ static void init_ranges(char **argv)
   int pagesize = 0;
 
   /*Round slot size up to nearest page size*/
-  slotsize=16*1024;
+  slotsize=1024*1024;
 #if CMK_HAS_GETPAGESIZE
   pagesize = getpagesize();
 #endif
@@ -2302,8 +2302,8 @@ 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(size+sizeof(CmiIsomallocBlock), 
-                                                  isomallocfn, isofreefn);
+      CtvAccessOther(tid,threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn);
+      printf("Other - request is %d\n",size);
     }
     blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccessOther(tid,threadpool),size+sizeof(CmiIsomallocBlock),1);
   } else {
@@ -2311,8 +2311,8 @@ void *CmiIsomalloc(int size, CthThread tid)
 #if ISOMALLOC_DEBUG
       printf("Init Mempool in %d\n",CthSelf());
 #endif
-      CtvAccess(threadpool) = mempool_init(size+sizeof(CmiIsomallocBlock), 
-                                                  isomallocfn, isofreefn);
+      CtvAccess(threadpool) = mempool_init(2*(size+sizeof(CmiIsomallocBlock)+sizeof(mempool_header))+sizeof(mempool_type), isomallocfn, isofreefn);
+      printf("Self - request is %d\n",size);
     }
     blk = (CmiIsomallocBlock*)mempool_malloc(CtvAccess(threadpool),size+sizeof(CmiIsomallocBlock),1);
   }
@@ -2443,7 +2443,7 @@ void CmiIsomallocFree(void *blockPtr)
   else if (blockPtr!=NULL)
   {
 #if USE_MEMPOOL_ISOMALLOC
-    mempool_free(CtvAccess(threadpool), blockPtr);
+    mempool_free(CtvAccess(threadpool), pointer2block(blockPtr));
 #else
     CmiIsomallocBlock *blk=pointer2block(blockPtr);
     CmiInt8 s=blk->slot; 
@@ -2537,10 +2537,9 @@ static void print_myslots();
 void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid)
 {
   mempool_type *mptr;
-  mempool_block *current, *mempools_head;
+  block_header *current, *block_head;
   void *newblock;
-  CmiInt8 slot;
-  int size;
+  CmiInt8 slot,size;
   int i, numBlocks = 0;
 
   if(!pup_isUnpacking(p)) {
@@ -2548,26 +2547,24 @@ void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid
     printf("My rank is %d Pupping for %d \n",CthSelf(),tid);
 #endif
     mptr = CtvAccessOther(tid,threadpool);
-    current = &(CtvAccessOther(tid,threadpool)->mempools_head);
+    current = &(CtvAccessOther(tid,threadpool)->block_head);
     while(current != NULL) {
       numBlocks++;
-      current = current->memblock_next?(mempool_block *)((char*)mptr+current->memblock_next):NULL;
-      //current = current->next;
+      current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
     }
 #if ISOMALLOC_DEBUG
     printf("Number of blocks packed %d\n",numBlocks);
 #endif
     pup_int(p,&numBlocks);
-    current = &(CtvAccessOther(tid,threadpool)->mempools_head);
+    current = &(CtvAccessOther(tid,threadpool)->block_head);
     while(current != NULL) {
-      pup_int(p,&current->size);
+      pup_int8(p,&current->size);
       pup_int8(p,&current->mem_hndl);
       pup_bytes(p,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->memblock_next?(mempool_block *)((char*)mptr+current->memblock_next):NULL;
-      //current = current->next;
+      current = current->block_next?(block_header *)((char*)mptr+current->block_next):NULL;
     }
   }
 
@@ -2577,7 +2574,7 @@ void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **lp, CthThread tid
     printf("Number of blocks to be unpacked %d\n",numBlocks);
 #endif
     for(i = 0; i < numBlocks; i++) { 
-      pup_int(p,&size);
+      pup_int8(p,&size);
       pup_int8(p,&slot);
       newblock = map_slots(slot,size/slotsize);
       pup_bytes(p,newblock,size);