Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Improve the integration of mmalloc and mc_memory into the mess.
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 6 May 2010 23:42:51 +0000 (23:42 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 6 May 2010 23:42:51 +0000 (23:42 +0000)
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

include/xbt/mmalloc.h
src/mc/mc_memory.c
src/mc/memory_map.c
src/xbt/mmalloc/attach.c
src/xbt/mmalloc/mmalloc.c
src/xbt/mmalloc/mmap-sup.c
src/xbt/mmalloc/mmprivate.h
src/xbt/mmalloc/sbrk-sup.c
src/xbt/xbt_main.c
src/xbt_modinter.h

index 98642f9..9ce4cd0 100644 (file)
@@ -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);
index 526d409..3f08a59 100644 (file)
@@ -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 */
index fb91333..0868ccc 100644 (file)
@@ -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);
   
index 99cf826..31e6a4b 100644 (file)
@@ -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) */
-
index bf3b69d..c7d1a07 100644 (file)
@@ -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;
index 81af351..46d43e8 100644 (file)
@@ -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 <unistd.h>    /* Prototypes for lseek */
 #endif
@@ -200,4 +198,3 @@ mmalloc_findbase (int size)
     }
   return ((void*) base);
 }
-#endif /* defined(HAVE_MMAP) */
index 3c83a4b..5f25ef6 100644 (file)
@@ -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 */
index d3b4f38..64e249f 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <string.h>    /* 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);
+}
index 71569a8..df635b1 100644 (file)
@@ -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. */
index 87f3766..279c741 100644 (file)
@@ -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 */