From: Martin Quinson Date: Mon, 8 Oct 2012 22:28:30 +0000 (+0200) Subject: Bug fix in mrealloc where the previous content could get lost X-Git-Tag: v3_8~99^2~5 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/6c85989bc5420b3fbc6373025a469b41315f7813?hp=0b662f11a46b8c74b930f4dd54822d859c6ba81e Bug fix in mrealloc where the previous content could get lost 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. --- diff --git a/include/xbt/mmalloc.h b/include/xbt/mmalloc.h index 0c706ee990..99d0b5bb47 100644 --- a/include/xbt/mmalloc.h +++ b/include/xbt/mmalloc.h @@ -29,9 +29,12 @@ */ 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); diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c index be68060138..7584c63335 100644 --- a/src/xbt/mmalloc/mmalloc.c +++ b/src/xbt/mmalloc/mmalloc.c @@ -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 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); diff --git a/src/xbt/mmalloc/mrealloc.c b/src/xbt/mmalloc/mrealloc.c index 23d0a1c202..c1078bdeaf 100644 --- a/src/xbt/mmalloc/mrealloc.c +++ b/src/xbt/mmalloc/mrealloc.c @@ -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;