Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Bug fix in mrealloc where the previous content could get lost
authorMartin Quinson <martin.quinson@loria.fr>
Mon, 8 Oct 2012 22:28:30 +0000 (00:28 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Mon, 8 Oct 2012 22:31:05 +0000 (00:31 +0200)
When reallocating a large block, mrealloc tries to be cleaver and
first frees the area before requesting it again to avoid a copy if
there is some free adjacent memory.

This trick obviously don't mix well with the mmalloc memseting the
allocated memory to 0 before returning it.

So, split the mmalloc in two, and use the non-memsetting one from
mrealloc.

include/xbt/mmalloc.h
src/xbt/mmalloc/mmalloc.c
src/xbt/mmalloc/mrealloc.c

index 0c706ee..99d0b5b 100644 (file)
  */
 typedef struct mdesc *xbt_mheap_t;
 
-/* Allocate SIZE bytes of memory.  */
+/* Allocate SIZE bytes of memory (and memset it to 0).  */
 extern void *mmalloc(xbt_mheap_t md, size_t size);
 
+/* Allocate SIZE bytes of memory (and don't mess with it) */
+void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size);
+
 /* Re-allocate the previously allocated block in void*, making the new block
    SIZE bytes long.  */
 extern void *mrealloc(xbt_mheap_t md, void *ptr, size_t size);
index be68060..7584c63 100644 (file)
@@ -106,8 +106,15 @@ static void *register_morecore(struct mdesc *mdp, size_t size)
 }
 
 /* Allocate memory from the heap.  */
-
-void *mmalloc(xbt_mheap_t mdp, size_t size)
+void *mmalloc(xbt_mheap_t mdp, size_t size) {
+  void *res= mmalloc_no_memset(mdp,size);
+  memset(res,0,size);
+  return res;
+}
+/* Spliting mmalloc this way is mandated by a trick in mrealloc, that gives
+   back the memory of big blocks to the system before reallocating them: we don't
+   want to loose the beginning of the area when this happens */
+void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size)
 {
   void *result;
   size_t block, blocks, lastblocks, start;
@@ -170,15 +177,12 @@ void *mmalloc(xbt_mheap_t mdp, size_t size)
       mdp -> heapstats.chunks_free--;
       mdp -> heapstats.bytes_free -= 1 << log;
 
-      memset(result, 0, requested_size);
-      
     } else {
       /* No free fragments of the desired size, so get a new block
          and break it into fragments, returning the first.  */
       //printf("(%s) No free fragment...",xbt_thread_self_name());
 
       result = mmalloc(mdp, BLOCKSIZE); // does not return NULL
-      memset(result, 0, requested_size);
 
       /* Link all fragments but the first into the free list, and mark their requested size to 0.  */
       block = BLOCK(result);
@@ -237,7 +241,6 @@ void *mmalloc(xbt_mheap_t mdp, size_t size)
           continue;
         }
         result = register_morecore(mdp, blocks * BLOCKSIZE);
-        memset(result, 0, requested_size);
 
         block = BLOCK(result);
         for (it=0;it<blocks;it++){
@@ -289,7 +292,6 @@ void *mmalloc(xbt_mheap_t mdp, size_t size)
     mdp -> heapstats.bytes_used += blocks * BLOCKSIZE;
     mdp -> heapstats.bytes_free -= blocks * BLOCKSIZE;
 
-    memset(result, 0, requested_size);
   }
   //printf("(%s) Done mallocing. Result is %p\n",xbt_thread_self_name(),result);fflush(stdout);
   return (result);
index 23d0a1c..c1078bd 100644 (file)
@@ -101,8 +101,9 @@ void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size)
 
     } else {
       /* Won't fit, so allocate a new region that will.
-         Free the old region first in case there is sufficient
-         adjacent free space to grow without moving. */
+         Free the old region first in case there is sufficient adjacent free space to grow without moving.
+         This trick mandates using a specific version of mmalloc that does not memset the memory to 0 after
+           action for obvious reasons. */
       blocks = mdp->heapinfo[block].busy_block.size;
       /* Prevent free from actually returning memory to the system.  */
       oldlimit = mdp->heaplimit;
@@ -110,9 +111,10 @@ void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size)
       mfree(mdp, ptr);
       mdp->heaplimit = oldlimit;
 
-      result = mmalloc(mdp, requested_size);
+      result = mmalloc_no_memset(mdp, requested_size);
       if (ptr != result)
         memmove(result, ptr, blocks * BLOCKSIZE);
+      /* FIXME: we should memset the end of the recently area */
     }
     break;