From: Gabriel Corona Date: Thu, 10 Jul 2014 13:48:16 +0000 (+0200) Subject: [mmalloc] Add new block type for heapinfo blocks X-Git-Tag: v3_12~890^2~1^2~4^2~9 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/0ab6b907319bfb2726f97ed2d21b9f4d6992ca86 [mmalloc] Add new block type for heapinfo blocks --- diff --git a/src/mc/mc_diff.c b/src/mc/mc_diff.c index 9748eeeef3..1c606b7db6 100644 --- a/src/mc/mc_diff.c +++ b/src/mc/mc_diff.c @@ -90,7 +90,8 @@ static void mmalloc_backtrace_display(void *addr) /* type = heap->heapinfo[block].type; */ /* switch(type){ */ - /* case -1 : /\* Free block *\/ */ + /* case MMALLOC_TYPE_HEAPINFO : */ + /* case MMALLOC_TYPE_FREE : /\* Free block *\/ */ /* fprintf(stderr, "Asked to display the backtrace of a block that is free. I'm puzzled\n"); */ /* xbt_abort(); */ /* break; */ @@ -444,16 +445,21 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i1], heap_region1, &heapinfo_temp1, sizeof(malloc_info)); malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i1], heap_region2, &heapinfo_temp2, sizeof(malloc_info)); - if (heapinfo1->type == -1) { /* Free block */ - i1++; + if (heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type == MMALLOC_TYPE_HEAPINFO) { /* Free block */ + i1 += heapinfo1->free_block.size; continue; } + if (heapinfo1->type < 0) { + fprintf(stderr, "Unkown mmalloc block type.\n"); + abort(); + } + addr_block1 = ((void *) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char *) ((xbt_mheap_t) state->s_heap)->heapbase)); - if (heapinfo1->type == 0) { /* Large block */ + if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) { /* Large block */ if (is_stack(addr_block1)) { for (k = 0; k < heapinfo1->busy_block.size; k++) @@ -512,7 +518,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info)); - if (heapinfo2b->type != 0) { + if (heapinfo2b->type != MMALLOC_TYPE_UNFRAGMENTED) { i2++; continue; } @@ -589,11 +595,17 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) while (i2 <= state->heaplimit && !equal) { malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info)); - if (heapinfo2b->type <= 0) { - i2++; + + if (heapinfo2b->type == MMALLOC_TYPE_FREE || heapinfo2b->type == MMALLOC_TYPE_HEAPINFO) { + i2 += heapinfo2b->free_block.size; continue; } + if (heapinfo2b->type < 0) { + fprintf(stderr, "Unkown mmalloc block type.\n"); + abort(); + } + for (j2 = 0; j2 < (size_t) (BLOCKSIZE >> heapinfo2b->type); j2++) { @@ -649,7 +661,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) for(i = 1; i <= state->heaplimit; i++) { malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i], heap_region1, &heapinfo_temp1, sizeof(malloc_info)); - if (heapinfo1->type == 0) { + if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) { if (i1 == state->heaplimit) { if (heapinfo1->busy_block.busy_size > 0) { if (state->equals_to1_(i, 0).valid == 0) { @@ -690,7 +702,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) for (i=1; i <= state->heaplimit; i++) { malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i], heap_region2, &heapinfo_temp2, sizeof(malloc_info)); - if (heapinfo2->type == 0) { + if (heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) { if (i1 == state->heaplimit) { if (heapinfo2->busy_block.busy_size > 0) { if (state->equals_to2_(i, 0).valid == 0) { @@ -1193,15 +1205,19 @@ int compare_heap_area(void *area1, void *area2, mc_snapshot_t snapshot1, malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[block1], heap_region1, &heapinfo_temp1, sizeof(malloc_info)); malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[block2], heap_region2, &heapinfo_temp2, sizeof(malloc_info)); - if ((heapinfo1->type == -1) && (heapinfo2->type == -1)) { /* Free block */ + if ((heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type==MMALLOC_TYPE_HEAPINFO) + && (heapinfo2->type == MMALLOC_TYPE_FREE || heapinfo2->type ==MMALLOC_TYPE_HEAPINFO)) { + /* Free block */ if (match_pairs) { match_equals(state, previous); xbt_dynar_free(&previous); } return 0; - } else if ((heapinfo1->type == 0) && (heapinfo2->type == 0)) { /* Complete block */ + } else if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED + && heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) { + /* Complete block */ // TODO, lookup variable type from block type as done for fragmented blocks @@ -1512,9 +1528,9 @@ static int get_pointed_area_size(void *area, int heap) || (block > state->heapsize1) || (block < 1)) return -1; - if (heapinfo[block].type == -1) { /* Free block */ + if (heapinfo[block].type == MMALLOC_TYPE_FREE || heapinfo[block].type == MMALLOC_TYPE_HEAPINFO) { /* Free block */ return -1; - } else if (heapinfo[block].type == 0) { /* Complete block */ + } else if (heapinfo[block].type == MMALLOC_TYPE_UNFRAGMENTED) { /* Complete block */ return (int) heapinfo[block].busy_block.busy_size; } else { frag = @@ -1615,12 +1631,13 @@ int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2) } else { - if (state->heapinfo1[i].type == -1) { /* Free block */ + if (state->heapinfo1[i].type == MMALLOC_TYPE_FREE + || state->heapinfo1[i].type == MMALLOC_TYPE_HAPINFO) { /* Free block */ i++; continue; } - if (state->heapinfo1[i].type == 0) { /* Large block */ + if (state->heapinfo1[i].type == MMALLOC_TYPE_UNFRAGMENTED) { /* Large block */ if (state->heapinfo1[i].busy_block.size != state->heapinfo2[i].busy_block.size) { diff --git a/src/xbt/mmalloc/mfree.c b/src/xbt/mmalloc/mfree.c index ca48a1e80f..5586cf5400 100644 --- a/src/xbt/mmalloc/mfree.c +++ b/src/xbt/mmalloc/mfree.c @@ -42,12 +42,17 @@ void mfree(struct mdesc *mdp, void *ptr) type = mdp->heapinfo[block].type; switch (type) { - case -1: /* Already free */ + case MMALLOC_TYPE_HEAPINFO: UNLOCK(mdp); - THROWF(system_error, 0, "Asked to free a fragment in a block that is already free. I'm puzzled\n"); + THROWF(system_error, 0, "Asked to free a fragment in a heapinfo block. I'm confused.\n"); + break; + + case MMALLOC_TYPE_FREE: /* Already free */ + 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: + case MMALLOC_TYPE_UNFRAGMENTED: /* Get as many statistics as early as we can. */ mdp -> heapstats.chunks_used--; mdp -> heapstats.bytes_used -= @@ -83,12 +88,12 @@ void mfree(struct mdesc *mdp, void *ptr) 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++) { - if (mdp->heapinfo[block+it].type <0) { + if (mdp->heapinfo[block+it].type < 0) { fprintf(stderr,"Internal Error: Asked to free a block already marked as free (block=%lu it=%d type=%lu). Please report this bug.\n", (unsigned long)block,it,(unsigned long)mdp->heapinfo[block].type); abort(); } - mdp->heapinfo[block+it].type = -1; + mdp->heapinfo[block+it].type = MMALLOC_TYPE_FREE; } block = i; @@ -108,7 +113,7 @@ void mfree(struct mdesc *mdp, void *ptr) (unsigned long)block,it,(unsigned long)mdp->heapinfo[block].free_block.size,(unsigned long)mdp->heapinfo[block].type); abort(); } - mdp->heapinfo[block+it].type = -1; + mdp->heapinfo[block+it].type = MMALLOC_TYPE_FREE; } } @@ -149,6 +154,11 @@ void mfree(struct mdesc *mdp, void *ptr) break; default: + if (type < 0) { + fprintf(stderr, "Unkown mmalloc block type.\n"); + abort(); + } + /* Do some of the statistics. */ mdp -> heapstats.chunks_used--; mdp -> heapstats.bytes_used -= 1 << type; @@ -178,7 +188,7 @@ void mfree(struct mdesc *mdp, void *ptr) xbt_swag_remove(&mdp->heapinfo[block],&mdp->fraghead[type]); /* pretend that this block is used and free it so that it gets properly coalesced with adjacent free blocks */ - mdp->heapinfo[block].type = 0; + mdp->heapinfo[block].type = MMALLOC_TYPE_UNFRAGMENTED; mdp->heapinfo[block].busy_block.size = 1; mdp->heapinfo[block].busy_block.busy_size = 0; diff --git a/src/xbt/mmalloc/mm_module.c b/src/xbt/mmalloc/mm_module.c index 4839cfe887..bb3fbceec6 100644 --- a/src/xbt/mmalloc/mm_module.c +++ b/src/xbt/mmalloc/mm_module.c @@ -362,11 +362,11 @@ size_t mmalloc_get_bytes_used(xbt_mheap_t heap){ int bytes = 0; while(i<=((struct mdesc *)heap)->heaplimit){ - if(((struct mdesc *)heap)->heapinfo[i].type == 0){ + if(((struct mdesc *)heap)->heapinfo[i].type == MMALLOC_TYPE_UNFRAGMENTED){ if(((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size > 0) bytes += ((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size; - }else if(((struct mdesc *)heap)->heapinfo[i].type > 0){ + } else if(((struct mdesc *)heap)->heapinfo[i].type > 0){ for(j=0; j < (size_t) (BLOCKSIZE >> ((struct mdesc *)heap)->heapinfo[i].type); j++){ if(((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j] > 0) bytes += ((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j]; @@ -381,9 +381,9 @@ size_t mmalloc_get_bytes_used(xbt_mheap_t heap){ ssize_t mmalloc_get_busy_size(xbt_mheap_t heap, void *ptr){ ssize_t block = ((char*)ptr - (char*)(heap->heapbase)) / BLOCKSIZE + 1; - if(heap->heapinfo[block].type == -1) + if(heap->heapinfo[block].type < 0) return -1; - else if(heap->heapinfo[block].type == 0) + else if(heap->heapinfo[block].type == MMALLOC_TYPE_UNFRAGMENTED) return heap->heapinfo[block].busy_block.busy_size; else{ ssize_t frag = ((uintptr_t) (ADDR2UINT (ptr) % (BLOCKSIZE))) >> heap->heapinfo[block].type; diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c index c91b4a06cb..84f4a5412d 100644 --- a/src/xbt/mmalloc/mmalloc.c +++ b/src/xbt/mmalloc/mmalloc.c @@ -48,6 +48,25 @@ static void *align(struct mdesc *mdp, size_t size) return (result); } +/** Initialise heapinfo about the heapinfo pages :) + * + */ +static void initialize_heapinfo_heapinfo(xbt_mheap_t mdp) +{ + // Update heapinfo about the heapinfo pages (!): + xbt_assert((uintptr_t) mdp->heapinfo % BLOCKSIZE == 0); + int block = BLOCK(mdp->heapinfo); + size_t nblocks = mdp->heapsize * sizeof(malloc_info) / BLOCKSIZE; + // Mark them as free: + for (size_t j=0; j!=nblocks; ++j) { + mdp->heapinfo[block+j].type = MMALLOC_TYPE_FREE; + mdp->heapinfo[block+j].free_block.size = 0; + mdp->heapinfo[block+j].free_block.next = 0; + mdp->heapinfo[block+j].free_block.prev = 0; + } + mdp->heapinfo[block].free_block.size = nblocks; +} + /* Finish the initialization of the mheap. If we want to inline it * properly, we need to make the align function publicly visible, too */ static void initialize(xbt_mheap_t mdp) @@ -55,17 +74,21 @@ static void initialize(xbt_mheap_t mdp) int i; malloc_info mi; /* to compute the offset of the swag hook */ + // Update mdp meta-data: mdp->heapsize = HEAP / BLOCKSIZE; mdp->heapinfo = (malloc_info *) align(mdp, mdp->heapsize * sizeof(malloc_info)); + mdp->heapbase = (void *) mdp->heapinfo; + mdp->flags |= MMALLOC_INITIALIZED; + // Update root heapinfo: memset((void *) mdp->heapinfo, 0, mdp->heapsize * sizeof(malloc_info)); - mdp->heapinfo[0].type=-1; + mdp->heapinfo[0].type = MMALLOC_TYPE_FREE; 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; + + initialize_heapinfo_heapinfo(mdp); for (i=0;ifraghead[i]), @@ -122,7 +145,7 @@ 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 */ for (it=0; itheapsize * sizeof(malloc_info)); it++){ - newinfo[BLOCK(oldinfo)+it].type = 0; + newinfo[BLOCK(oldinfo)+it].type = MMALLOC_TYPE_UNFRAGMENTED; newinfo[BLOCK(oldinfo)+it].busy_block.ignore = 0; } @@ -130,6 +153,8 @@ static void *register_morecore(struct mdesc *mdp, size_t size) newinfo[BLOCK(oldinfo)].busy_block.busy_size = size; mfree(mdp, (void *) oldinfo); mdp->heapsize = newsize; + + initialize_heapinfo_heapinfo(mdp); } mdp->heaplimit = BLOCK((char *) result + size); @@ -283,9 +308,10 @@ void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size) block = BLOCK(result); for (it=0;itheapinfo[block+it].type = 0; + mdp->heapinfo[block+it].type = MMALLOC_TYPE_UNFRAGMENTED; mdp->heapinfo[block+it].busy_block.busy_size = 0; mdp->heapinfo[block+it].busy_block.ignore = 0; + mdp->heapinfo[block+it].busy_block.size = 0; } mdp->heapinfo[block].busy_block.size = blocks; mdp->heapinfo[block].busy_block.busy_size = requested_size; @@ -324,7 +350,7 @@ void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size) } for (it=0;itheapinfo[block+it].type = 0; + mdp->heapinfo[block+it].type = MMALLOC_TYPE_UNFRAGMENTED; mdp->heapinfo[block+it].busy_block.busy_size = 0; mdp->heapinfo[block+it].busy_block.ignore = 0; } diff --git a/src/xbt/mmalloc/mmprivate.h b/src/xbt/mmalloc/mmprivate.h index 69a6a75178..9100070a48 100644 --- a/src/xbt/mmalloc/mmprivate.h +++ b/src/xbt/mmalloc/mmprivate.h @@ -122,6 +122,11 @@ typedef struct s_heap_area_pair{ int fragment2; }s_heap_area_pair_t, *heap_area_pair_t; +#define MMALLOC_TYPE_HEAPINFO (-2) +#define MMALLOC_TYPE_FREE (-1) +#define MMALLOC_TYPE_UNFRAGMENTED 0 +/* >0 values are fragmented blocks */ + /* Data structure giving per-block information. * * There is one such structure in the mdp->heapinfo array per block used in that heap, diff --git a/src/xbt/mmalloc/mrealloc.c b/src/xbt/mmalloc/mrealloc.c index 1a6d100209..67e7bc6599 100644 --- a/src/xbt/mmalloc/mrealloc.c +++ b/src/xbt/mmalloc/mrealloc.c @@ -59,12 +59,17 @@ void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size) type = mdp->heapinfo[block].type; switch (type) { - case -1: + case MMALLOC_TYPE_HEAPINFO: + fprintf(stderr, "Asked realloc a fragment coming from a heapinfo block. I'm confused.\n"); + abort(); + break; + + case MMALLOC_TYPE_FREE: fprintf(stderr, "Asked realloc a fragment coming from a *free* block. I'm puzzled.\n"); abort(); break; - case 0: + case MMALLOC_TYPE_UNFRAGMENTED: /* Maybe reallocate a large block to a small fragment. */ if (size <= BLOCKSIZE / 2) { // Full block -> Fragment; no need to optimize for time @@ -84,7 +89,7 @@ void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size) /* The new size is smaller; return excess memory to the free list. */ //printf("(%s) return excess memory...",xbt_thread_self_name()); for (it= block+blocks; it< mdp->heapinfo[block].busy_block.size ; it++){ - mdp->heapinfo[it].type = 0; // FIXME that should be useless, type should already be 0 here + mdp->heapinfo[it].type = MMALLOC_TYPE_UNFRAGMENTED; // FIXME that should be useless, type should already be 0 here mdp->heapinfo[it].busy_block.ignore = 0; } @@ -127,6 +132,11 @@ void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size) default: /* Fragment -> ??; type=logarithm to base two of the fragment size. */ + if (type < 0) { + fprintf(stderr, "Unkown mmalloc block type.\n"); + abort(); + } + if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type)) { /* The new size is the same kind of fragment. */ //printf("(%s) new size is same kind of fragment...",xbt_thread_self_name());