From: Marion Guthmuller Date: Tue, 19 Jun 2012 13:57:30 +0000 (+0200) Subject: model-checker : add stats in mmalloc X-Git-Tag: v3_8~563^2~15 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/6d215aa449fe86894819be267aa2ae30cb5b151c model-checker : add stats in mmalloc --- diff --git a/src/xbt/mmalloc/mfree.c b/src/xbt/mmalloc/mfree.c index 5d544122ba..c750d9ad3c 100644 --- a/src/xbt/mmalloc/mfree.c +++ b/src/xbt/mmalloc/mfree.c @@ -44,6 +44,13 @@ void mfree(struct mdesc *mdp, void *ptr) break; case 0: + /* Get as many statistics as early as we can. */ + mdp -> heapstats.chunks_used--; + mdp -> heapstats.bytes_used -= + 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. */ @@ -84,6 +91,7 @@ void mfree(struct mdesc *mdp, void *ptr) 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; + mdp -> heapstats.chunks_free++; /* Mark all my ex-blocks as free */ for (it=0; itheapinfo[block].free_block.size; it++) { if (mdp->heapinfo[block+it].type <0) { @@ -105,6 +113,7 @@ void mfree(struct mdesc *mdp, void *ptr) 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; + mdp -> heapstats.chunks_free--; } /* Now see if we can return stuff to the system. */ @@ -129,6 +138,13 @@ void mfree(struct mdesc *mdp, void *ptr) break; default: + /* Do some of the statistics. */ + mdp -> heapstats.chunks_used--; + mdp -> heapstats.bytes_used -= 1 << type; + 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) + @@ -150,7 +166,13 @@ void mfree(struct mdesc *mdp, void *ptr) mdp->heapinfo[block].type = 0; mdp->heapinfo[block].busy_block.size = 1; mdp->heapinfo[block].busy_block.busy_size = 0; - + + /* Keep the statistics accurate. */ + mdp -> heapstats.chunks_used++; + mdp -> heapstats.bytes_used += BLOCKSIZE; + mdp -> heapstats.chunks_free -= BLOCKSIZE >> type; + mdp -> heapstats.bytes_free -= BLOCKSIZE; + mfree((void *) mdp, (void *) ADDRESS(block)); } else if (mdp->heapinfo[block].busy_frag.nfree != 0) { /* If some fragments of this block are free, link this diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c index bbdc9375f9..37f8c6b933 100644 --- a/src/xbt/mmalloc/mmalloc.c +++ b/src/xbt/mmalloc/mmalloc.c @@ -164,6 +164,12 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) RESIDUAL(next->next, BLOCKSIZE) >> log; } + /* Update the statistics. */ + mdp -> heapstats.chunks_used++; + mdp -> heapstats.bytes_used += 1 << log; + mdp -> heapstats.chunks_free--; + mdp -> heapstats.bytes_free -= 1 << log; + } else { /* No free fragments of the desired size, so get a new block and break it into fragments, returning the first. */ @@ -190,6 +196,10 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) mdp->heapinfo[block].type = log; mdp->heapinfo[block].busy_frag.nfree = i - 1; mdp->heapinfo[block].busy_frag.first = i - 1; + + mdp -> heapstats.chunks_free += (BLOCKSIZE >> log) - 1; + mdp -> heapstats.bytes_free += BLOCKSIZE - (1 << log); + mdp -> heapstats.bytes_used -= BLOCKSIZE - (1 << log); } } else { /* Large allocation to receive one or more blocks. @@ -231,7 +241,8 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) mdp->heapinfo[block].busy_block.size = blocks; mdp->heapinfo[block].busy_block.busy_size = requested_size; mdp->heapinfo[block].busy_block.bt_size=xbt_backtrace_no_malloc(mdp->heapinfo[block].busy_block.bt,XBT_BACKTRACE_SIZE); - + mdp -> heapstats.chunks_used++; + mdp -> heapstats.bytes_used += blocks * BLOCKSIZE; return result; } /* Need large block(s), but found some in the existing heap */ @@ -267,6 +278,10 @@ void *mmalloc(xbt_mheap_t mdp, size_t size) mdp->heapinfo[block].busy_block.busy_size = requested_size; //mdp->heapinfo[block].busy_block.bt_size = 0; mdp->heapinfo[block].busy_block.bt_size = xbt_backtrace_no_malloc(mdp->heapinfo[block].busy_block.bt,XBT_BACKTRACE_SIZE); + + mdp -> heapstats.chunks_used++; + mdp -> heapstats.bytes_used += blocks * BLOCKSIZE; + mdp -> heapstats.bytes_free -= blocks * BLOCKSIZE; } //printf("(%s) Done mallocing. Result is %p\n",xbt_thread_self_name(),result);fflush(stdout); return (result); diff --git a/src/xbt/mmalloc/mmprivate.h b/src/xbt/mmalloc/mmprivate.h index 4273e0d4a9..d0eb81c30e 100644 --- a/src/xbt/mmalloc/mmprivate.h +++ b/src/xbt/mmalloc/mmprivate.h @@ -96,6 +96,16 @@ struct list { struct list *prev; }; +/* Statistics available to the user. */ +struct mstats +{ + size_t bytes_total; /* Total size of the heap. */ + size_t chunks_used; /* Chunks allocated by the user. */ + size_t bytes_used; /* Byte total of user-allocated chunks. */ + size_t chunks_free; /* Chunks in the free list. */ + size_t bytes_free; /* Byte total of chunks in the free list. */ +}; + /* Data structure giving per-block information. * * There is one such structure in the mdp->heapinfo array per block used in that heap, @@ -222,6 +232,10 @@ struct mdesc { int fd; + /* Instrumentation. */ + + struct mstats heapstats; + }; int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2);