From 87817af89b2262a403386b38a0ec95388a6df5ad Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Thu, 2 Feb 2012 17:45:21 +0100 Subject: [PATCH 1/1] Simplify the malloc_info structure containing the metadata of a given block in mmalloc * Less structures in union in structure in union inception madness We're using a less portable anonymous union, but gcc handles that since maybe 15 years, so that should be cool. * We can now determine from looking at it whether the block is busy or free, without having to search in which list the block is. That was useles to other usages of mmalloc, but this is very interesting when comparing heaps. Moreover, it comes for free: it has exactly the same (memory) cost when the block is busy, and we have a plenty of place in the block to store that this it free when it is actually free. Please note that this information is not updated when the block is freed yet. (splitting the commit just in case someone tries to read it later: this one is almost automatic refactoring) --- src/xbt/mmalloc/mfree.c | 57 ++++++++++++++++-------------- src/xbt/mmalloc/mm_legacy.c | 58 +++++++++++++++--------------- src/xbt/mmalloc/mmalloc.c | 70 ++++++++++++++++++------------------- src/xbt/mmalloc/mmorecore.c | 1 - src/xbt/mmalloc/mmprivate.h | 44 +++++++++++------------ src/xbt/mmalloc/mrealloc.c | 21 ++++++----- 6 files changed, 127 insertions(+), 124 deletions(-) diff --git a/src/xbt/mmalloc/mfree.c b/src/xbt/mmalloc/mfree.c index 59cac74b08..db57be44c5 100644 --- a/src/xbt/mmalloc/mfree.c +++ b/src/xbt/mmalloc/mfree.c @@ -30,7 +30,10 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) } - type = mdp->heapinfo[block].busy.type; + type = mdp->heapinfo[block].type; + if (type<0) + THROWF(arg_error,0,"Asked to free a fragment in a block that is already free. I'm puzzled"); + switch (type) { case 0: /* Find the free cluster previous to this one in the free list. @@ -39,40 +42,40 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) i = mdp->heapindex; if (i > block) { while (i > block) { - i = mdp->heapinfo[i].free.prev; + i = mdp->heapinfo[i].free_block.prev; } } else { do { - i = mdp->heapinfo[i].free.next; + i = mdp->heapinfo[i].free_block.next; } while ((i != 0) && (i < block)); - i = mdp->heapinfo[i].free.prev; + i = mdp->heapinfo[i].free_block.prev; } /* Determine how to link this block into the free list. */ - if (block == i + mdp->heapinfo[i].free.size) { + if (block == i + mdp->heapinfo[i].free_block.size) { /* Coalesce this block with its predecessor. */ - mdp->heapinfo[i].free.size += mdp->heapinfo[block].busy.info.block.size; + mdp->heapinfo[i].free_block.size += mdp->heapinfo[block].busy_block.size; block = i; } else { /* Really link this block back into the free list. */ - mdp->heapinfo[block].free.size = mdp->heapinfo[block].busy.info.block.size; - mdp->heapinfo[block].free.next = mdp->heapinfo[i].free.next; - mdp->heapinfo[block].free.prev = i; - mdp->heapinfo[i].free.next = block; - mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev = block; + 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; } /* Now that the block is linked in, see if we can coalesce it with its successor (by deleting its successor from the list and adding in its size). */ - if (block + mdp->heapinfo[block].free.size == - mdp->heapinfo[block].free.next) { - mdp->heapinfo[block].free.size - += mdp->heapinfo[mdp->heapinfo[block].free.next].free.size; - mdp->heapinfo[block].free.next - = mdp->heapinfo[mdp->heapinfo[block].free.next].free.next; - mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev = block; + if (block + mdp->heapinfo[block].free_block.size == + mdp->heapinfo[block].free_block.next) { + mdp->heapinfo[block].free_block.size + += mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.size; + mdp->heapinfo[block].free_block.next + = mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.next; + mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev = block; } /* Now see if we can return stuff to the system. */ @@ -100,9 +103,9 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) /* Get the address of the first free fragment in this block. */ prev = (struct list *) ((char *) ADDRESS(block) + - (mdp->heapinfo[block].busy.info.frag.first << type)); + (mdp->heapinfo[block].busy_frag.first << type)); - if (mdp->heapinfo[block].busy.info.frag.nfree == + if (mdp->heapinfo[block].busy_frag.nfree == (BLOCKSIZE >> type) - 1) { /* If all fragments of this block are free, remove them from the fragment list and free the whole block. */ @@ -114,12 +117,12 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) if (next != NULL) { next->prev = prev->prev; } - mdp->heapinfo[block].busy.type = 0; - mdp->heapinfo[block].busy.info.block.size = 1; - mdp->heapinfo[block].busy.info.block.busy_size = 0; + mdp->heapinfo[block].type = 0; + mdp->heapinfo[block].busy_block.size = 1; + mdp->heapinfo[block].busy_block.busy_size = 0; mfree((void *) mdp, (void *) ADDRESS(block)); - } else if (mdp->heapinfo[block].busy.info.frag.nfree != 0) { + } else if (mdp->heapinfo[block].busy_frag.nfree != 0) { /* If some fragments of this block are free, link this fragment into the fragment list after the first free fragment of this block. */ @@ -130,14 +133,14 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr) if (next->next != NULL) { next->next->prev = next; } - ++mdp->heapinfo[block].busy.info.frag.nfree; + ++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 it is the first free fragment of this block. */ prev = (struct list *) ptr; - mdp->heapinfo[block].busy.info.frag.nfree = 1; - mdp->heapinfo[block].busy.info.frag.first = + mdp->heapinfo[block].busy_frag.nfree = 1; + mdp->heapinfo[block].busy_frag.first = RESIDUAL(ptr, BLOCKSIZE) >> type; prev->next = mdp->fraghead[type].next; prev->prev = &mdp->fraghead[type]; diff --git a/src/xbt/mmalloc/mm_legacy.c b/src/xbt/mmalloc/mm_legacy.c index f757d7cd65..b353835634 100644 --- a/src/xbt/mmalloc/mm_legacy.c +++ b/src/xbt/mmalloc/mm_legacy.c @@ -231,12 +231,12 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap block_free1 = mdp1->heapindex; block_free2 = mdp2->heapindex; - while(mdp1->heapinfo[block_free1].free.prev != 0){ - block_free1 = mdp1->heapinfo[block_free1].free.prev; + while(mdp1->heapinfo[block_free1].free_block.prev != 0){ + block_free1 = mdp1->heapinfo[block_free1].free_block.prev; } - while(mdp2->heapinfo[block_free2].free.prev != 0){ - block_free2 = mdp1->heapinfo[block_free2].free.prev; + while(mdp2->heapinfo[block_free2].free_block.prev != 0){ + block_free2 = mdp1->heapinfo[block_free2].free_block.prev; } if(block_free1 != block_free2){ @@ -250,7 +250,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap first_block_free = block_free1; - if(mdp1->heapinfo[first_block_free].free.size != mdp2->heapinfo[first_block_free].free.size){ + if(mdp1->heapinfo[first_block_free].free_block.size != mdp2->heapinfo[first_block_free].free_block.size){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different size (in blocks) of the first free cluster"); errors++; @@ -261,9 +261,9 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap /* Check busy blocks (circular checking)*/ - i = first_block_free + mdp1->heapinfo[first_block_free].free.size; + i = first_block_free + mdp1->heapinfo[first_block_free].free_block.size; - if(mdp1->heapinfo[first_block_free].free.next != mdp2->heapinfo[first_block_free].free.next){ + if(mdp1->heapinfo[first_block_free].free_block.next != mdp2->heapinfo[first_block_free].free_block.next){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different next block free"); errors++; @@ -273,7 +273,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap } block_free = first_block_free; - next_block_free = mdp1->heapinfo[first_block_free].free.next; + next_block_free = mdp1->heapinfo[first_block_free].free_block.next; if(next_block_free == 0) next_block_free = mdp1->heaplimit; @@ -282,7 +282,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap while(iheapinfo[i].busy.type != mdp2->heapinfo[i].busy.type){ + if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different type of busy block"); errors++; @@ -294,9 +294,9 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); - switch(mdp1->heapinfo[i].busy.type){ + switch(mdp1->heapinfo[i].type){ //FIXME deal with type<0 == free case 0 : - if(mdp1->heapinfo[i].busy.info.block.size != mdp2->heapinfo[i].busy.info.block.size){ + if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different size of a large cluster"); errors++; @@ -304,20 +304,20 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap return 1; } }else{ - if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy.info.block.size * BLOCKSIZE)) != 0){ + if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ - XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy.info.block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2); + XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy_block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2); errors++; }else{ return 1; } } } - i = i+mdp1->heapinfo[i].busy.info.block.size; + i = i+mdp1->heapinfo[i].busy_block.size; break; default : - if(mdp1->heapinfo[i].busy.info.frag.nfree != mdp2->heapinfo[i].busy.info.frag.nfree){ + if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different free fragments in the fragmented block %zu", i); errors++; @@ -325,7 +325,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap return 1; } }else{ - if(mdp1->heapinfo[i].busy.info.frag.first != mdp2->heapinfo[i].busy.info.frag.first){ + if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different first free fragments in the block %zu", i); errors++; @@ -333,7 +333,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap return 1; } }else{ - frag_size = pow(2,mdp1->heapinfo[i].busy.type); + frag_size = pow(2,mdp1->heapinfo[i].type); for(j=0 ; j< (BLOCKSIZE/frag_size); j++){ if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ @@ -357,7 +357,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap if( i != first_block_free){ - if(mdp1->heapinfo[block_free].free.next != mdp2->heapinfo[block_free].free.next){ + if(mdp1->heapinfo[block_free].free_block.next != mdp2->heapinfo[block_free].free_block.next){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different next block free"); errors++; @@ -366,16 +366,16 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap } } - block_free = mdp1->heapinfo[block_free].free.next; - next_block_free = mdp1->heapinfo[block_free].free.next; + block_free = mdp1->heapinfo[block_free].free_block.next; + next_block_free = mdp1->heapinfo[block_free].free_block.next; - i = block_free + mdp1->heapinfo[block_free].free.size; + i = block_free + mdp1->heapinfo[block_free].free_block.size; if((next_block_free == 0) && (i != mdp1->heaplimit)){ while(i < mdp1->heaplimit){ - if(mdp1->heapinfo[i].busy.type != mdp2->heapinfo[i].busy.type){ + if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different type of busy block"); errors++; @@ -387,9 +387,9 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); - switch(mdp1->heapinfo[i].busy.type){ + switch(mdp1->heapinfo[i].type){ case 0 : - if(mdp1->heapinfo[i].busy.info.block.size != mdp2->heapinfo[i].busy.info.block.size){ + if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different size of a large cluster"); errors++; @@ -397,7 +397,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap return 1; } }else{ - if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy.info.block.size * BLOCKSIZE)) != 0){ + if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different data in block %zu (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2); errors++; @@ -407,11 +407,11 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap } } - i = i+mdp1->heapinfo[i].busy.info.block.size; + i = i+mdp1->heapinfo[i].busy_block.size; break; default : - if(mdp1->heapinfo[i].busy.info.frag.nfree != mdp2->heapinfo[i].busy.info.frag.nfree){ + if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different free fragments in the fragmented block %zu", i); errors++; @@ -419,7 +419,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap return 1; } }else{ - if(mdp1->heapinfo[i].busy.info.frag.first != mdp2->heapinfo[i].busy.info.frag.first){ + if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ XBT_DEBUG("Different first free fragments in the block %zu", i); errors++; @@ -427,7 +427,7 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap return 1; } }else{ - frag_size = pow(2,mdp1->heapinfo[i].busy.type); + frag_size = pow(2,mdp1->heapinfo[i].type); for(j=0 ; j< (BLOCKSIZE/frag_size); j++){ if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){ if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){ diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c index 355b24c1a3..7cef260b6a 100644 --- a/src/xbt/mmalloc/mmalloc.c +++ b/src/xbt/mmalloc/mmalloc.c @@ -55,8 +55,8 @@ static int initialize(xbt_mheap_t mdp) return (0); } memset((void *) mdp->heapinfo, 0, mdp->heapsize * sizeof(malloc_info)); - mdp->heapinfo[0].free.size = 0; - mdp->heapinfo[0].free.next = mdp->heapinfo[0].free.prev = 0; + mdp->heapinfo[0].free_block.size = 0; + mdp->heapinfo[0].free_block.next = mdp->heapinfo[0].free_block.prev = 0; mdp->heapindex = 0; mdp->heapbase = (void *) mdp->heapinfo; mdp->flags |= MMALLOC_INITIALIZED; @@ -92,9 +92,9 @@ static void *register_morecore(struct mdesc *mdp, size_t size) /* mark the space previously occupied by the block info as free by first marking it * as occupied in the regular way, and then freing it */ - newinfo[BLOCK(oldinfo)].busy.type = 0; - newinfo[BLOCK(oldinfo)].busy.info.block.size = BLOCKIFY(mdp->heapsize * sizeof(malloc_info)); - newinfo[BLOCK(oldinfo)].busy.info.block.busy_size = size; + newinfo[BLOCK(oldinfo)].type = 0; + newinfo[BLOCK(oldinfo)].busy_block.size = BLOCKIFY(mdp->heapsize * sizeof(malloc_info)); + newinfo[BLOCK(oldinfo)].busy_block.busy_size = size; __mmalloc_free(mdp, (void *) oldinfo); mdp->heapsize = newsize; } @@ -154,8 +154,8 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) next->next->prev = next->prev; } block = BLOCK(result); - if (--mdp->heapinfo[block].busy.info.frag.nfree != 0) { - mdp->heapinfo[block].busy.info.frag.first = + if (--mdp->heapinfo[block].busy_frag.nfree != 0) { + mdp->heapinfo[block].busy_frag.first = RESIDUAL(next->next, BLOCKSIZE) >> log; } @@ -182,9 +182,9 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) /* Initialize the nfree and first counters for this block. */ block = BLOCK(result); - mdp->heapinfo[block].busy.type = log; - mdp->heapinfo[block].busy.info.frag.nfree = i - 1; - mdp->heapinfo[block].busy.info.frag.first = i - 1; + mdp->heapinfo[block].type = log; + mdp->heapinfo[block].busy_frag.nfree = i - 1; + mdp->heapinfo[block].busy_frag.first = i - 1; } } else { /* Large allocation to receive one or more blocks. @@ -193,14 +193,14 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) space we will have to get more memory from the system. */ blocks = BLOCKIFY(size); start = block = MALLOC_SEARCH_START; - while (mdp->heapinfo[block].free.size < blocks) { - block = mdp->heapinfo[block].free.next; + while (mdp->heapinfo[block].free_block.size < blocks) { + block = mdp->heapinfo[block].free_block.next; if (block == start) { /* Need to get more from the system. Check to see if the new core will be contiguous with the final free block; if so we don't need to get as much. */ - block = mdp->heapinfo[0].free.prev; - lastblocks = mdp->heapinfo[block].free.size; + block = mdp->heapinfo[0].free_block.prev; + lastblocks = mdp->heapinfo[block].free_block.size; if (mdp->heaplimit != 0 && block + lastblocks == mdp->heaplimit && mmorecore(mdp, 0) == ADDRESS(block + lastblocks) && @@ -208,9 +208,9 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) /* Which block we are extending (the `final free block' referred to above) might have changed, if it got combined with a freed info table. */ - block = mdp->heapinfo[0].free.prev; + block = mdp->heapinfo[0].free_block.prev; - mdp->heapinfo[block].free.size += (blocks - lastblocks); + mdp->heapinfo[block].free_block.size += (blocks - lastblocks); continue; } result = register_morecore(mdp, blocks * BLOCKSIZE); @@ -218,9 +218,9 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) return (NULL); } block = BLOCK(result); - mdp->heapinfo[block].busy.type = 0; - mdp->heapinfo[block].busy.info.block.size = blocks; - mdp->heapinfo[block].busy.info.block.busy_size = size; + mdp->heapinfo[block].type = 0; + mdp->heapinfo[block].busy_block.size = blocks; + mdp->heapinfo[block].busy_block.busy_size = size; return (result); } } @@ -228,30 +228,30 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) /* At this point we have found a suitable free list entry. Figure out how to remove what we need from the list. */ result = ADDRESS(block); - if (mdp->heapinfo[block].free.size > blocks) { + if (mdp->heapinfo[block].free_block.size > blocks) { /* The block we found has a bit left over, so relink the tail end back into the free list. */ - mdp->heapinfo[block + blocks].free.size - = mdp->heapinfo[block].free.size - blocks; - mdp->heapinfo[block + blocks].free.next - = mdp->heapinfo[block].free.next; - mdp->heapinfo[block + blocks].free.prev - = mdp->heapinfo[block].free.prev; - mdp->heapinfo[mdp->heapinfo[block].free.prev].free.next - = mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev + mdp->heapinfo[block + blocks].free_block.size + = mdp->heapinfo[block].free_block.size - blocks; + mdp->heapinfo[block + blocks].free_block.next + = mdp->heapinfo[block].free_block.next; + mdp->heapinfo[block + blocks].free_block.prev + = mdp->heapinfo[block].free_block.prev; + mdp->heapinfo[mdp->heapinfo[block].free_block.prev].free_block.next + = mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev = mdp->heapindex = block + blocks; } else { /* The block exactly matches our requirements, so just remove it from the list. */ - mdp->heapinfo[mdp->heapinfo[block].free.next].free.prev - = mdp->heapinfo[block].free.prev; - mdp->heapinfo[mdp->heapinfo[block].free.prev].free.next - = mdp->heapindex = mdp->heapinfo[block].free.next; + mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev + = mdp->heapinfo[block].free_block.prev; + mdp->heapinfo[mdp->heapinfo[block].free_block.prev].free_block.next + = mdp->heapindex = mdp->heapinfo[block].free_block.next; } - mdp->heapinfo[block].busy.type = 0; - mdp->heapinfo[block].busy.info.block.size = blocks; - mdp->heapinfo[block].busy.info.block.busy_size = size; + mdp->heapinfo[block].type = 0; + mdp->heapinfo[block].busy_block.size = blocks; + mdp->heapinfo[block].busy_block.busy_size = size; } //printf("(%s) Done mallocing. Result is %p\n",xbt_thread_self_name(),result);fflush(stdout); return (result); diff --git a/src/xbt/mmalloc/mmorecore.c b/src/xbt/mmalloc/mmorecore.c index 9f31583e6f..9e2d22ed53 100644 --- a/src/xbt/mmalloc/mmorecore.c +++ b/src/xbt/mmalloc/mmorecore.c @@ -21,7 +21,6 @@ #include #include "mmprivate.h" -#include "xbt/ex.h" /* Cache the pagesize for the current host machine. Note that if the host does not readily provide a getpagesize() function, we need to emulate it diff --git a/src/xbt/mmalloc/mmprivate.h b/src/xbt/mmalloc/mmprivate.h index 370e5198cd..e886092f75 100644 --- a/src/xbt/mmalloc/mmprivate.h +++ b/src/xbt/mmalloc/mmprivate.h @@ -16,6 +16,7 @@ #include "portable.h" #include "xbt/xbt_os_thread.h" #include "xbt/mmalloc.h" +#include "xbt/ex.h" #include #ifdef HAVE_LIMITS_H @@ -106,30 +107,27 @@ const char *xbt_thread_self_name(void); * - add the same for each fragments * - make room to store the backtrace of where the fragment were malloced, too. */ -typedef union { +typedef struct { + int type; /* 0: busy large block + >0: busy fragmented (fragments of size 2^type bytes) + <0: free block */ + union { /* Heap information for a busy block. */ - struct { - /* Zero for a large block, or positive giving the - logarithm to the base two of the fragment size. */ - int type; - union { - struct { - size_t nfree; /* Free fragments in a fragmented block. */ - size_t first; /* First free fragment of the block. */ - } frag; - struct { - size_t size; /* Size (in blocks) of a large cluster. */ - size_t busy_size; - } block; - } info; - } busy; - /* Heap information for a free block (that may be the first of - a free cluster). */ - struct { - size_t size; /* Size (in blocks) of a free cluster. */ - size_t next; /* Index of next free cluster. */ - size_t prev; /* Index of previous free cluster. */ - } free; + struct { + size_t nfree; /* Free fragments in a fragmented block. */ + size_t first; /* First free fragment of the block. */ + } busy_frag; + struct { + size_t size; /* Size (in blocks) of a large cluster. */ + size_t busy_size; + } busy_block; + /* Heap information for a free block (that may be the first of a free cluster). */ + struct { + size_t size; /* Size (in blocks) of a free cluster. */ + size_t next; /* Index of next free cluster. */ + size_t prev; /* Index of previous free cluster. */ + } free_block; + }; } malloc_info; /* Doubly linked lists of free fragments. */ diff --git a/src/xbt/mmalloc/mrealloc.c b/src/xbt/mmalloc/mrealloc.c index 3dd60c2418..ea4d7f6878 100644 --- a/src/xbt/mmalloc/mrealloc.c +++ b/src/xbt/mmalloc/mrealloc.c @@ -46,7 +46,10 @@ void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size) block = BLOCK(ptr); - type = mdp->heapinfo[block].busy.type; + type = mdp->heapinfo[block].type; + if (type<0) + THROWF(arg_error,0,"Asked realloc a fragment comming from a *free* block. I'm puzzled."); + switch (type) { case 0: /* Maybe reallocate a large block to a small fragment. */ @@ -63,24 +66,24 @@ void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size) /* The new size is a large allocation as well; see if we can hold it in place. */ blocks = BLOCKIFY(size); - if (blocks < mdp->heapinfo[block].busy.info.block.size) { + if (blocks < mdp->heapinfo[block].busy_block.size) { /* The new size is smaller; return excess memory to the free list. */ //printf("(%s) return excess memory...",xbt_thread_self_name()); - mdp->heapinfo[block + blocks].busy.type = 0; - mdp->heapinfo[block + blocks].busy.info.block.size - = mdp->heapinfo[block].busy.info.block.size - blocks; - mdp->heapinfo[block].busy.info.block.size = blocks; - mdp->heapinfo[block].busy.info.block.busy_size = size; + mdp->heapinfo[block + blocks].type = 0; + mdp->heapinfo[block + blocks].busy_block.size + = mdp->heapinfo[block].busy_block.size - blocks; + mdp->heapinfo[block].busy_block.size = blocks; + mdp->heapinfo[block].busy_block.busy_size = size; mfree(mdp, ADDRESS(block + blocks)); result = ptr; - } else if (blocks == mdp->heapinfo[block].busy.info.block.size) { + } else if (blocks == mdp->heapinfo[block].busy_block.size) { /* No size change necessary. */ result = ptr; } 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. */ - blocks = mdp->heapinfo[block].busy.info.block.size; + blocks = mdp->heapinfo[block].busy_block.size; /* Prevent free from actually returning memory to the system. */ oldlimit = mdp->heaplimit; mdp->heaplimit = 0; -- 2.20.1