From: mquinson Date: Thu, 6 May 2010 23:42:51 +0000 (+0000) Subject: Improve the integration of mmalloc and mc_memory into the mess. X-Git-Tag: SVN~34 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/f2d062a16daf5602b56944a78c51c36ae317a7fa Improve the integration of mmalloc and mc_memory into the mess. By default (ie, when passed a NULL mmalloc descriptor), mmalloc and friends use a mmap based implementation (instead of the old, slow sbrk one). mc_memory makes sure that we pass something else than NULL as mmalloc descriptor to mmalloc function only if the model-checker is used. (the model-checker is not activable yet -- the integration is maybe next commit) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7710 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/include/xbt/mmalloc.h b/include/xbt/mmalloc.h index 98642f9c06..9ce4cd00db 100644 --- a/include/xbt/mmalloc.h +++ b/include/xbt/mmalloc.h @@ -55,6 +55,9 @@ extern void* mmalloc_getkey (void* md, int keynum); // FIXME: this function is not implemented anymore? //extern int mmalloc_errno (void* md); +/* return the heap used when NULL is passed as first argument to any mm* function */ +extern void *mmalloc_get_default_md(void); + extern int mmtrace(void); extern void* mmalloc_findbase(int size); diff --git a/src/mc/mc_memory.c b/src/mc/mc_memory.c index 526d40970a..3f08a5992c 100644 --- a/src/mc/mc_memory.c +++ b/src/mc/mc_memory.c @@ -9,18 +9,17 @@ extern char *basename (__const char *__filename); -#define HEAP_OFFSET 20480000 /* Safety gap from the heap's break adress */ #define STD_HEAP_SIZE 20480000 /* Maximum size of the system's heap */ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_memory, mc, "Logging specific to MC (memory)"); /* Pointers to each of the heap regions to use */ -void *std_heap=NULL; -void *raw_heap=NULL; -void *actual_heap=NULL; +void *std_heap=NULL; /* memory erased each time the MC stuff rollbacks to the beginning. Almost everything goes here */ +void *raw_heap=NULL; /* memory persistent over the MC rollbacks. Only MC stuff should go there */ +void *actual_heap=NULL; /* The heap we are currently using. Either std_heap or raw_heap. Controlled by macros MC_SET_RAW_MEM/MC_UNSET_RAW_MEM */ -/* Pointers to the begining and end of the .data and .bss segment of libsimgrid */ +/* Pointers to the beginning and end of the .data and .bss segment of libsimgrid */ /* They are initialized once at memory_init */ void *libsimgrid_data_addr_start = NULL; size_t libsimgrid_data_size = 0; @@ -30,20 +29,18 @@ size_t libsimgrid_data_size = 0; void MC_memory_init() { /* Create the first region HEAP_OFFSET bytes after the heap break address */ - std_heap = mmalloc_attach(-1, (char *)sbrk(0) + HEAP_OFFSET); + std_heap = mmalloc_get_default_md(); xbt_assert(std_heap != NULL); -/* Create the sencond region a page after the first one ends */ -/* FIXME: do not hardcode the page size to 4096 */ - raw_heap = mmalloc_attach(-1, (char *)(std_heap) + STD_HEAP_SIZE + 4096); +/* Create the second region a page after the first one ends */ + raw_heap = mmalloc_attach(-1, (char *)(std_heap) + STD_HEAP_SIZE + getpagesize()); xbt_assert(raw_heap != NULL); MC_SET_RAW_MEM; /* Get the start address and size of libsimgrid's data segment */ -/* CAVEAT: Here we are assuming several things, first that get_memory_map() */ -/* returns an array with the maps sorted from lower addresses to higher */ -/* ones. Second, that libsimgrid's data takes ONLY ONE page. */ +/* CAVEAT: Here we are assuming that get_memory_map() */ +/* returns an array with the maps sorted from lower addresses to higher ones. */ int i; char *libname, *tmp; @@ -58,9 +55,19 @@ void MC_memory_init() tmp = xbt_strdup(maps->regions[i].pathname); libname = basename(tmp); - if( strncmp("libsimgrid.so.2.0.0", libname, 18) == 0 && maps->regions[i].perms & MAP_WRITE){ //FIXME: do not hardcode +#if 0 + if (maps->regions[i].perms & MAP_WRITE && + maps->regions[i].pathname[0] != '\0' && /* do not take anonymous segments: what are they? */ + strcmp("[heap]",maps->regions[i].pathname) && /* do not take standard heap: mmalloc saves it already */ + strcmp("[stack]",maps->regions[i].pathname) /* this is maestro's stack. No need to save it */ + ) { + /* FIXME: we should save the data of more segments, in a list of block to save */ + } +#endif + /* for now, we only save the data of libsimgrid (FIXME) */ + if( strncmp("libsimgrid.so.", libname, 14) == 0 && maps->regions[i].perms & MAP_WRITE){ libsimgrid_data_addr_start = maps->regions[i].start_addr; - libsimgrid_data_size = (size_t)((char *)maps->regions[i+1].end_addr - (char *)maps->regions[i].start_addr); + libsimgrid_data_size = (size_t)((char *)maps->regions[i+1].start_addr - (char *)maps->regions[i].start_addr); xbt_free(tmp); break; } @@ -82,8 +89,7 @@ void MC_memory_exit() actual_heap = NULL; } -void *malloc(size_t n) -{ +void *malloc(size_t n) { void *ret = mmalloc(actual_heap, n); DEBUG2("%zu bytes were allocated at %p",n, ret); @@ -93,6 +99,7 @@ void *malloc(size_t n) void *calloc(size_t nmemb, size_t size) { size_t total_size = nmemb * size; + void *ret = mmalloc(actual_heap, total_size); /* Fill the allocated memory with zeroes to mimic calloc behaviour */ diff --git a/src/mc/memory_map.c b/src/mc/memory_map.c index fb91333798..0868ccc537 100644 --- a/src/mc/memory_map.c +++ b/src/mc/memory_map.c @@ -19,8 +19,7 @@ memory_map_t get_memory_map(void) /* to be returned. */ fp = fopen("/proc/self/maps","r"); - if(!fp) - xbt_abort(); + xbt_assert0(fp,"Cannot open /proc/self/maps to investigate the memory map of the process. Please report this bug."); ret = xbt_new0(s_memory_map_t,1); diff --git a/src/xbt/mmalloc/attach.c b/src/xbt/mmalloc/attach.c index 99cf8266c3..31e6a4baed 100644 --- a/src/xbt/mmalloc/attach.c +++ b/src/xbt/mmalloc/attach.c @@ -34,8 +34,6 @@ Boston, MA 02111-1307, USA. */ #endif -#if defined(HAVE_MMAP) - /* Forward declarations/prototypes for local functions */ static struct mdesc *reuse (int fd); @@ -206,18 +204,3 @@ reuse (int fd) return (mdp); } -#else /* !defined (HAVE_MMAP) */ - -/* For systems without mmap, the library still supplies an entry point - to link to, but trying to initialize access to an mmap'd managed region - always fails. */ - -/* ARGSUSED */ -void* -mmalloc_attach (int fd, void* baseaddr) -{ - return (NULL); -} - -#endif /* defined (HAVE_MMAP) */ - diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c index bf3b69d19f..c7d1a07fac 100644 --- a/src/xbt/mmalloc/mmalloc.c +++ b/src/xbt/mmalloc/mmalloc.c @@ -109,9 +109,7 @@ morecore (struct mdesc *mdp, size_t size) /* Allocate memory from the heap. */ void* -mmalloc (md, size) - void* md; - size_t size; +mmalloc (void *md, size_t size) { struct mdesc *mdp; void* result; diff --git a/src/xbt/mmalloc/mmap-sup.c b/src/xbt/mmalloc/mmap-sup.c index 81af351294..46d43e818b 100644 --- a/src/xbt/mmalloc/mmap-sup.c +++ b/src/xbt/mmalloc/mmap-sup.c @@ -9,8 +9,6 @@ /* 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. */ -#if defined(HAVE_MMAP) - #ifdef HAVE_UNISTD_H #include /* Prototypes for lseek */ #endif @@ -200,4 +198,3 @@ mmalloc_findbase (int size) } return ((void*) base); } -#endif /* defined(HAVE_MMAP) */ diff --git a/src/xbt/mmalloc/mmprivate.h b/src/xbt/mmalloc/mmprivate.h index 3c83a4b6cf..5f25ef673c 100644 --- a/src/xbt/mmalloc/mmprivate.h +++ b/src/xbt/mmalloc/mmprivate.h @@ -294,16 +294,13 @@ extern struct mdesc *__mmalloc_default_mdp; /* Initialize the first use of the default malloc descriptor, which uses an sbrk() region. */ -extern struct mdesc *__mmalloc_sbrk_init (void); +extern struct mdesc *__mmalloc_create_default_mdp (void); /* Grow or shrink a contiguous mapped region using mmap(). - Works much like sbrk() */ - -#if defined(HAVE_MMAP) + Works much like sbrk(), only faster */ extern void* __mmalloc_mmap_morecore (struct mdesc *mdp, int size); -#endif /* Remap a mmalloc region that was previously mapped. */ @@ -317,9 +314,7 @@ extern void* __mmalloc_remap_core (struct mdesc *mdp); #define MD_TO_MDP(md) \ ((md) == NULL \ - ? (__mmalloc_default_mdp == NULL \ - ? __mmalloc_sbrk_init () \ - : __mmalloc_default_mdp) \ + ? __mmalloc_default_mdp \ : (struct mdesc *) (md)) #endif /* __MMPRIVATE_H */ diff --git a/src/xbt/mmalloc/sbrk-sup.c b/src/xbt/mmalloc/sbrk-sup.c index d3b4f38898..64e249fe15 100644 --- a/src/xbt/mmalloc/sbrk-sup.c +++ b/src/xbt/mmalloc/sbrk-sup.c @@ -12,6 +12,7 @@ #include /* Prototypes for memcpy, memmove, memset, etc */ +#include "xbt.h" #include "mmprivate.h" static void* sbrk_morecore (struct mdesc *mdp, int size); @@ -48,43 +49,19 @@ sbrk_morecore (mdp, size) return (result); } -/* Initialize the default malloc descriptor if this is the first time - a request has been made to use the default sbrk'd region. +#define HEAP_OFFSET 20480000 /* Safety gap from the heap's break address */ - Since no alignment guarantees are made about the initial value returned - by sbrk, test the initial value and (if necessary) sbrk enough additional - memory to start off with alignment to BLOCKSIZE. We actually only need - it aligned to an alignment suitable for any object, so this is overkill. - But at most it wastes just part of one BLOCKSIZE chunk of memory and - minimizes portability problems by avoiding us having to figure out - what the actual minimal alignment is. The rest of the malloc code - avoids this as well, by always aligning to the minimum of the requested - size rounded up to a power of two, or to BLOCKSIZE. - - Note that we are going to use some memory starting at this initial sbrk - address for the sbrk region malloc descriptor, which is a struct, so the - base address must be suitably aligned. */ - -struct mdesc * -__mmalloc_sbrk_init (void) -{ - void* base; - unsigned int adj; - - base = sbrk (0); - adj = RESIDUAL (base, BLOCKSIZE); - if (adj != 0) - { - sbrk (BLOCKSIZE - adj); - base = sbrk (0); - } - __mmalloc_default_mdp = (struct mdesc *) sbrk (sizeof (struct mdesc)); - memset ((char *) __mmalloc_default_mdp, 0, sizeof (struct mdesc)); - __mmalloc_default_mdp -> morecore = sbrk_morecore; - __mmalloc_default_mdp -> base = base; - __mmalloc_default_mdp -> breakval = __mmalloc_default_mdp -> top = sbrk (0); - __mmalloc_default_mdp -> fd = -1; - return (__mmalloc_default_mdp); +void *mmalloc_get_default_md(void) { + return __mmalloc_default_mdp; } - +/* Initialize the default malloc descriptor. */ +#include "xbt_modinter.h" +void mmalloc_preinit(void) { + __mmalloc_default_mdp = mmalloc_attach(-1, (char *)sbrk(0) + HEAP_OFFSET); + xbt_assert(__mmalloc_default_mdp != NULL); +} +void mmalloc_postexit(void) { + /* Do not detach the default mdp or ldl won't be able to free the memory it allocated since we're in memory */ + // mmalloc_detach(__mmalloc_default_mdp); +} diff --git a/src/xbt/xbt_main.c b/src/xbt/xbt_main.c index 71569a876a..df635b1584 100644 --- a/src/xbt/xbt_main.c +++ b/src/xbt/xbt_main.c @@ -79,6 +79,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { #endif static void xbt_preinit(void) { + mmalloc_preinit(); xbt_log_preinit(); /* Connect our log channels: that must be done manually under windows */ @@ -121,6 +122,7 @@ static void xbt_postexit(void) { xbt_log_postexit(); free(xbt_binary_name); + mmalloc_postexit(); } /** @brief Initialize the xbt mechanisms. */ diff --git a/src/xbt_modinter.h b/src/xbt_modinter.h index 87f37666da..279c741815 100644 --- a/src/xbt_modinter.h +++ b/src/xbt_modinter.h @@ -25,4 +25,7 @@ void xbt_dict_postexit(void); void xbt_os_thread_mod_preinit(void); void xbt_os_thread_mod_postexit(void); +void mmalloc_preinit(void); +void mmalloc_postexit(void); + #endif /* XBT_MODINTER_H */