// 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);
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;
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;
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;
}
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);
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 */
/* 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);
#endif
-#if defined(HAVE_MMAP)
-
/* Forward declarations/prototypes for local functions */
static struct mdesc *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) */
-
/* 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;
/* 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
}
return ((void*) base);
}
-#endif /* defined(HAVE_MMAP) */
/* 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. */
#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 */
#include <string.h> /* Prototypes for memcpy, memmove, memset, etc */
+#include "xbt.h"
#include "mmprivate.h"
static void* sbrk_morecore (struct mdesc *mdp, int 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);
+}
#endif
static void xbt_preinit(void) {
+ mmalloc_preinit();
xbt_log_preinit();
/* Connect our log channels: that must be done manually under windows */
xbt_log_postexit();
free(xbt_binary_name);
+ mmalloc_postexit();
}
/** @brief Initialize the xbt mechanisms. */
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 */