From 72a8adff27c51a64b9e2e95e561d8d6950310568 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Thu, 2 Feb 2012 20:43:32 +0100 Subject: [PATCH] ensure that free block are marked as such --- src/xbt/mmalloc/mfree.c | 15 +++++++++++++-- src/xbt/mmalloc/mmalloc.c | 6 ++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/xbt/mmalloc/mfree.c b/src/xbt/mmalloc/mfree.c index db57be44c5..41eefb106d 100644 --- a/src/xbt/mmalloc/mfree.c +++ b/src/xbt/mmalloc/mfree.c @@ -21,6 +21,7 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) size_t block; register size_t i; struct list *prev, *next; + int it; block = BLOCK(ptr); @@ -54,16 +55,25 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) /* Determine how to link this block into the free list. */ if (block == i + mdp->heapinfo[i].free_block.size) { + /* Coalesce this block with its predecessor. */ mdp->heapinfo[i].free_block.size += mdp->heapinfo[block].busy_block.size; + /* Mark all my ex-blocks as free */ + for (it=0; itheapinfo[block].busy_block.size; it++) + mdp->heapinfo[block+it].type = -1; + block = i; } else { + //fprintf(stderr,"Free block %d to %d (as a new chunck)\n",block,block+mdp->heapinfo[block].busy_block.size); /* Really link this block back into the free list. */ mdp->heapinfo[block].free_block.size = mdp->heapinfo[block].busy_block.size; mdp->heapinfo[block].free_block.next = mdp->heapinfo[i].free_block.next; mdp->heapinfo[block].free_block.prev = i; mdp->heapinfo[i].free_block.next = block; mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev = block; + /* Mark all my ex-blocks as free */ + for (it=0; itheapinfo[block].free_block.size; it++) + mdp->heapinfo[block+it].type = -1; } /* Now that the block is linked in, see if we can coalesce it @@ -117,6 +127,7 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) if (next != NULL) { next->prev = prev->prev; } + /* pretend the block is used and free it so that it gets properly coalesced with adjacent free blocks */ mdp->heapinfo[block].type = 0; mdp->heapinfo[block].busy_block.size = 1; mdp->heapinfo[block].busy_block.busy_size = 0; @@ -135,8 +146,8 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) } ++mdp->heapinfo[block].busy_frag.nfree; } else { - /* No fragments of this block are free, so link this - fragment into the fragment list and announce that + /* No fragments of this block were free before the one we just released, + * so link this fragment into the fragment list and announce that it is the first free fragment of this block. */ prev = (struct list *) ptr; mdp->heapinfo[block].busy_frag.nfree = 1; diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c index 7cef260b6a..29451d1587 100644 --- a/src/xbt/mmalloc/mmalloc.c +++ b/src/xbt/mmalloc/mmalloc.c @@ -55,6 +55,7 @@ static int initialize(xbt_mheap_t mdp) return (0); } memset((void *) mdp->heapinfo, 0, mdp->heapsize * sizeof(malloc_info)); + mdp->heapinfo[0].type=-1; mdp->heapinfo[0].free_block.size = 0; mdp->heapinfo[0].free_block.next = mdp->heapinfo[0].free_block.prev = 0; mdp->heapindex = 0; @@ -194,6 +195,11 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) blocks = BLOCKIFY(size); start = block = MALLOC_SEARCH_START; while (mdp->heapinfo[block].free_block.size < blocks) { + if (mdp->heapinfo[block].type >=0) { + fprintf(stderr,"Internal error: found a free block not marked as such (block=%lu type=%lu). Please report this bug.\n",(unsigned long)block,(unsigned long)mdp->heapinfo[block].type); + abort(); + } + block = mdp->heapinfo[block].free_block.next; if (block == start) { /* Need to get more from the system. Check to see if -- 2.20.1