Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
set size_used negative for free fragment/block
[simgrid.git] / src / xbt / mmalloc / mfree.c
index f452a9e..cbdea22 100644 (file)
@@ -11,6 +11,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "mmprivate.h"
+#include "xbt/ex.h"
 
 /* Return memory to the heap.
    Like `mfree' but don't call a mfree_hook if there is one.  */
@@ -19,7 +20,7 @@
 void mfree(struct mdesc *mdp, void *ptr)
 {
   int type;
-  size_t block;
+  size_t block, frag_nb;
   register size_t i;
   struct list *prev, *next;
   int it;
@@ -39,8 +40,8 @@ void mfree(struct mdesc *mdp, void *ptr)
 
   switch (type) {
   case -1: /* Already free */
-    fprintf(stderr,"Asked to free a fragment in a block that is already free. I'm puzzled\n");
-    abort();
+    UNLOCK(mdp);
+    THROWF(system_error, 0, "Asked to free a fragment in a block that is already free. I'm puzzled\n");
     break;
     
   case 0:
@@ -50,7 +51,7 @@ void mfree(struct mdesc *mdp, void *ptr)
       mdp -> heapinfo[block].busy_block.size * BLOCKSIZE;
     mdp -> heapstats.bytes_free +=
       mdp -> heapinfo[block].busy_block.size * BLOCKSIZE;
-    
+
     /* Find the free cluster previous to this one in the free list.
        Start searching at the last block referenced; this may benefit
        programs with locality of allocation.  */
@@ -144,12 +145,21 @@ void mfree(struct mdesc *mdp, void *ptr)
     mdp -> heapstats.chunks_free++;
     mdp -> heapstats.bytes_free += 1 << type;
 
-    
     /* Get the address of the first free fragment in this block.  */
     prev = (struct list *)
       ((char *) ADDRESS(block) +
        (mdp->heapinfo[block].busy_frag.first << type));
 
+    /* Set size used in the fragment to 0 */
+    frag_nb = RESIDUAL(ptr, BLOCKSIZE) >> type;
+
+    if( mdp->heapinfo[block].busy_frag.frag_size[frag_nb] == -1){
+      UNLOCK(mdp);
+      THROWF(system_error, 0, "Asked to free a fragment that is already free. I'm puzzled\n");
+    }
+
+    mdp->heapinfo[block].busy_frag.frag_size[frag_nb] = -1;
+
     if (mdp->heapinfo[block].busy_frag.nfree ==
         (BLOCKSIZE >> type) - 1) {
       /* If all fragments of this block are free, remove them
@@ -192,8 +202,7 @@ void mfree(struct mdesc *mdp, void *ptr)
        it is the first free fragment of this block. */
       prev = (struct list *) ptr;
       mdp->heapinfo[block].busy_frag.nfree = 1;
-      mdp->heapinfo[block].busy_frag.first =
-        RESIDUAL(ptr, BLOCKSIZE) >> type;
+      mdp->heapinfo[block].busy_frag.first = frag_nb;
       prev->next = mdp->fraghead[type].next;
       prev->prev = &mdp->fraghead[type];
       prev->prev->next = prev;