X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/49e85177c669d793e84242983a1b1f430e47184e..05736ee0ede974fcf9fb60a13a40c50d62fcc19d:/src/xbt/mmalloc/mmalloc.c diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c index 2fb4338de2..f04b8635d7 100644 --- a/src/xbt/mmalloc/mmalloc.c +++ b/src/xbt/mmalloc/mmalloc.c @@ -1,15 +1,16 @@ -/* Memory allocator `malloc'. - Copyright 1990, 1991, 1992 Free Software Foundation +/* Memory allocator `malloc'. */ - Written May 1989 by Mike Haertel. - Heavily modified Mar 1992 by Fred Fish for mmap'd version. */ - -/* Copyright (c) 2010-2014. The SimGrid Team. +/* Copyright (c) 2010-2015. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +/* Copyright 1990, 1991, 1992 Free Software Foundation + + Written May 1989 by Mike Haertel. + Heavily modified Mar 1992 by Fred Fish for mmap'd version. */ + #include /* Prototypes for memcpy, memmove, memset, etc */ #include #include "mmprivate.h" @@ -47,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) @@ -54,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]), @@ -96,9 +120,12 @@ static void *register_morecore(struct mdesc *mdp, size_t size) /* Copy old info into new location */ oldinfo = mdp->heapinfo; newinfo = (malloc_info *) align(mdp, newsize * sizeof(malloc_info)); - memset(newinfo, 0, newsize * sizeof(malloc_info)); memcpy(newinfo, oldinfo, mdp->heapsize * sizeof(malloc_info)); + /* Initialise the new blockinfo : */ + memset((char*) newinfo + mdp->heapsize * sizeof(malloc_info), 0, + (newsize - mdp->heapsize)* sizeof(malloc_info)); + /* Update the swag of busy blocks containing free fragments by applying the offset to all swag_hooks. Yeah. My hand is right in the fan and I still type */ size_t offset=((char*)newinfo)-((char*)oldinfo); @@ -118,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; } @@ -126,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); @@ -136,8 +165,9 @@ 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 *res= mmalloc_no_memset(mdp,size); -// fprintf(stderr,"malloc(%zu)~>%p\n",size,res); - memset(res,0,size); + if (mdp->options & XBT_MHEAP_OPTION_MEMSET) { + memset(res,0,size); + } return res; } /* Spliting mmalloc this way is mandated by a trick in mrealloc, that gives @@ -147,13 +177,13 @@ void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size) { void *result; size_t block, blocks, lastblocks, start; - register size_t i; - register size_t log; + size_t i; + size_t log; int it; size_t requested_size = size; // The amount of memory requested by user, for real - /* Work even if the user was stupid enough to ask a ridicullously small block (even 0-length), + /* Work even if the user was stupid enough to ask a ridiculously small block (even 0-length), * ie return a valid block that can be realloced and freed. * glibc malloc does not use this trick but return a constant pointer, but we need to enlist the free fragments later on. */ @@ -236,7 +266,7 @@ void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size) mdp->heapinfo[block].busy_frag.ignore[0] = 0; //xbt_backtrace_no_malloc(mdp->heapinfo[block].busy_frag.bt[0],XBT_BACKTRACE_SIZE); //xbt_libunwind_backtrace(mdp->heapinfo[block].busy_frag.bt[0],XBT_BACKTRACE_SIZE); - + /* update stats */ mdp -> heapstats.chunks_free += (BLOCKSIZE >> log) - 1; mdp -> heapstats.bytes_free += BLOCKSIZE - (1 << log); @@ -278,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; @@ -319,15 +350,16 @@ 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; + mdp->heapinfo[block+it].busy_block.size = 0; } mdp->heapinfo[block].busy_block.size = blocks; - mdp->heapinfo[block].busy_block.busy_size = requested_size; + 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->heapinfo[block].busy_block.bt_size = xbt_libunwind_backtrace(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;