Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Simplify the mmalloc library further
authorMartin Quinson <martin.quinson@loria.fr>
Wed, 1 Feb 2012 16:30:58 +0000 (17:30 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Wed, 1 Feb 2012 16:30:58 +0000 (17:30 +0100)
* Stop playing with void* for the heap descriptors and introduce the
  xbt_mheap_t datatype for that.
* Don't try to make it work when mmalloc and friends are called with
  NULL as a first argument.

I added a pimple that mmalloc_preinit returns the default mhead after
creating it to simplify the code of the legacy functions that check
that this default mhead exist or create it before using it.

This extra check should be useless if mmalloc_preinit were called soon
enough since it's in the critical path, but the performance of
model-checking is not a concern yet: only getting something working
matters for now.

12 files changed:
include/xbt/mmalloc.h
src/xbt/mmalloc/attach.c
src/xbt/mmalloc/detach.c
src/xbt/mmalloc/mcalloc.c
src/xbt/mmalloc/mfree.c
src/xbt/mmalloc/mm_legacy.c
src/xbt/mmalloc/mmalloc.c
src/xbt/mmalloc/mmemalign.c
src/xbt/mmalloc/mmprivate.h
src/xbt/mmalloc/mrealloc.c
src/xbt/mmalloc/mvalloc.c
src/xbt_modinter.h

index d3d23a7..74643cd 100644 (file)
 #  include <stdio.h>            /* for NULL */
 #endif
 
+/* Datatype representing a separate heap. The whole point of the mmalloc module
+ * is to allow several such heaps in the process. It thus works by redefining
+ * all the classical memory management functions (malloc and friends) with an
+ * extra first argument: the heap in which the memory is to be taken.
+ *
+ * The heap structure itself is an opaque object that shouldnt be messed with.
+ */
+typedef struct mdesc *xbt_mheap_t;
+
 /* Allocate SIZE bytes of memory.  */
-extern void *mmalloc(void *md, size_t size);
+extern void *mmalloc(xbt_mheap_t md, size_t size);
 
 /* Re-allocate the previously allocated block in void*, making the new block
    SIZE bytes long.  */
-extern void *mrealloc(void *md, void *ptr, size_t size);
+extern void *mrealloc(xbt_mheap_t md, void *ptr, size_t size);
 
 /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0.  */
-extern void *mcalloc(void *md, size_t nmemb, size_t size);
+extern void *mcalloc(xbt_mheap_t md, size_t nmemb, size_t size);
 
 /* Free a block allocated by `mmalloc', `mrealloc' or `mcalloc'.  */
-extern void mfree(void *md, void *ptr);
+extern void mfree(xbt_mheap_t md, void *ptr);
 
 /* Allocate SIZE bytes allocated to ALIGNMENT bytes.  */
-extern void *mmemalign(void *md, size_t alignment, size_t size);
+extern void *mmemalign(xbt_mheap_t md, size_t alignment, size_t size);
 
 /* Allocate SIZE bytes on a page boundary.  */
-extern void *mvalloc(void *md, size_t size);
+extern void *mvalloc(xbt_mheap_t md, size_t size);
 
-extern void *mmalloc_attach(int fd, void *baseaddr);
+extern xbt_mheap_t mmalloc_attach(int fd, void *baseaddr);
 
-extern void mmalloc_detach_no_free(void *md);
+extern void mmalloc_detach_no_free(xbt_mheap_t md);
 
-extern void *mmalloc_detach(void *md);
+extern void *mmalloc_detach(xbt_mheap_t md);
 
 /* return the heap used when NULL is passed as first argument to any mm* function */
-extern void *mmalloc_get_default_md(void);
+extern xbt_mheap_t mmalloc_get_default_md(void);
 
 extern void *mmalloc_findbase(int size);
 
-extern int mmalloc_compare_heap(void *h1, void *h2, void *std_heap_addr);
-
-extern void mmalloc_display_info_heap(void *h);
+extern void mmalloc_display_info_heap(xbt_mheap_t h);
 
 /* To change the heap used when using the legacy version malloc/free/realloc and such */
-void mmalloc_set_current_heap(void *new_heap);
-void *mmalloc_get_current_heap(void);
+void mmalloc_set_current_heap(xbt_mheap_t new_heap);
+xbt_mheap_t mmalloc_get_current_heap(void);
 
+int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr);
 
 
 #endif                          /* MMALLOC_H */
index 531a436..7741a0b 100644 (file)
@@ -68,10 +68,10 @@ static struct mdesc *reuse(int fd);
 
    On failure returns NULL. */
 
-void *mmalloc_attach(int fd, void *baseaddr)
+xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
 {
   struct mdesc mtemp;
-  struct mdesc *mdp;
+  xbt_mheap_t mdp;
   void *mbase;
   struct stat sbuf;
 
@@ -143,8 +143,8 @@ void *mmalloc_attach(int fd, void *baseaddr)
       mdp->next_mdesc = (struct mdesc *)mbase;
     UNLOCK(mdp);
   }
-  
-  return ((void *) mbase);
+
+  return mbase;
 }
 
 /* Given an valid file descriptor on an open file, test to see if that file
index 8df6e5e..6ed1398 100644 (file)
@@ -18,7 +18,7 @@
  * This is for example useful for the base region where ldl stores its data
  *   because it leaves the place after us.
  */
-void mmalloc_detach_no_free(void *md)
+void mmalloc_detach_no_free(xbt_mheap_t md)
 {
   struct mdesc *mdp = md;
 
@@ -42,9 +42,8 @@ void mmalloc_detach_no_free(void *md)
    region we are about to unmap, so we first make a local copy of it on the
    stack and use the copy. */
 
-void *mmalloc_detach(void *md)
+void *mmalloc_detach(xbt_mheap_t mdp)
 {
-  struct mdesc *mdp = (struct mdesc *)md;
   struct mdesc mtemp, *mdptemp;
 
   if (mdp != NULL) {
@@ -55,8 +54,8 @@ void *mmalloc_detach(void *md)
 
     mdptemp->next_mdesc = mdp->next_mdesc;
 
-    mmalloc_detach_no_free(md);
-    mtemp = *(struct mdesc *) md;
+    mmalloc_detach_no_free(mdp);
+    mtemp = *mdp;
 
     /* Now unmap all the pages associated with this region by asking for a
        negative increment equal to the current size of the region. */
@@ -66,14 +65,14 @@ void *mmalloc_detach(void *md)
         NULL) {
       /* Deallocating failed.  Update the original malloc descriptor
          with any changes */
-      *(struct mdesc *) md = mtemp;
+      *mdp = mtemp;
     } else {
       if (mtemp.flags & MMALLOC_DEVZERO) {
         close(mtemp.fd);
       }
-      md = NULL;
+      mdp = NULL;
     }
   }
 
-  return (md);
+  return (mdp);
 }
index f80953f..6c94d46 100644 (file)
@@ -15,7 +15,7 @@
 /* Allocate an array of NMEMB elements each SIZE bytes long.
    The entire array is initialized to zeros.  */
 
-void *mcalloc(void *md, register size_t nmemb, register size_t size)
+void *mcalloc(xbt_mheap_t md, register size_t nmemb, register size_t size)
 {
   register void *result;
 
index 185fe6b..ff89699 100644 (file)
@@ -152,13 +152,11 @@ void __mmalloc_free(struct mdesc *mdp, void *ptr)
 
 /* Return memory to the heap.  */
 
-void mfree(void *md, void *ptr)
+void mfree(xbt_mheap_t mdp, void *ptr)
 {
-  struct mdesc *mdp;
   register struct alignlist *l;
 
   if (ptr != NULL) {
-    mdp = MD_TO_MDP(md);
     for (l = mdp->aligned_blocks; l != NULL; l = l->next) {
       if (l->aligned == ptr) {
         l->aligned = NULL;      /* Mark the slot in the list as free. */
index f676ae8..0de0dd2 100644 (file)
@@ -17,19 +17,19 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_mm_legacy, xbt,
    for mmalloc/mrealloc/mfree operations which do not supply an explicit
    descriptor.  This allows mmalloc() to provide
    backwards compatibility with the non-mmap'd version. */
-struct mdesc *__mmalloc_default_mdp;
+xbt_mheap_t __mmalloc_default_mdp = NULL;
 
 
-static void *__mmalloc_current_heap = NULL;     /* The heap we are currently using. */
+static xbt_mheap_t __mmalloc_current_heap = NULL;     /* The heap we are currently using. */
 
 #include "xbt_modinter.h"
 
-void *mmalloc_get_current_heap(void)
+xbt_mheap_t mmalloc_get_current_heap(void)
 {
   return __mmalloc_current_heap;
 }
 
-void mmalloc_set_current_heap(void *new_heap)
+void mmalloc_set_current_heap(xbt_mheap_t new_heap)
 {
   __mmalloc_current_heap = new_heap;
 }
@@ -37,11 +37,8 @@ void mmalloc_set_current_heap(void *new_heap)
 #ifdef MMALLOC_WANT_OVERIDE_LEGACY
 void *malloc(size_t n)
 {
-  void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_MMAP
-  if (!mdp)
-    mmalloc_preinit();
-#endif
+  xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
   LOCK(mdp);
   void *ret = mmalloc(mdp, n);
   UNLOCK(mdp);
@@ -52,11 +49,8 @@ void *malloc(size_t n)
 void *calloc(size_t nmemb, size_t size)
 {
   size_t total_size = nmemb * size;
-  void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_MMAP
-  if (!mdp)
-    mmalloc_preinit();
-#endif
+  xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
   LOCK(mdp);
   void *ret = mmalloc(mdp, total_size);
   UNLOCK(mdp);
@@ -70,11 +64,8 @@ void *calloc(size_t nmemb, size_t size)
 void *realloc(void *p, size_t s)
 {
   void *ret = NULL;
-  void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_MMAP
-  if (!mdp)
-    mmalloc_preinit();
-#endif
+  xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
   LOCK(mdp);
   if (s) {
     if (p)
@@ -91,10 +82,8 @@ void *realloc(void *p, size_t s)
 
 void free(void *p)
 {
-  void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_GTNETS
-  if(!mdp) return;
-#endif
+  xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
   LOCK(mdp);
   mfree(mdp, p);
   UNLOCK(mdp);
@@ -108,7 +97,7 @@ void free(void *p)
  * valgrind. */
 #define HEAP_OFFSET   (128UL<<20)
 
-void *mmalloc_get_default_md(void)
+xbt_mheap_t mmalloc_get_default_md(void)
 {
   xbt_assert(__mmalloc_default_mdp);
   return __mmalloc_default_mdp;
@@ -116,7 +105,7 @@ void *mmalloc_get_default_md(void)
 
 static void mmalloc_fork_prepare(void)
 {
-  struct mdesc* mdp = NULL;
+  xbt_mheap_t mdp = NULL;
   if ((mdp =__mmalloc_default_mdp)){
     while(mdp){
       LOCK(mdp);
@@ -130,7 +119,7 @@ static void mmalloc_fork_prepare(void)
 
 static void mmalloc_fork_parent(void)
 {
-  struct mdesc* mdp = NULL;
+  xbt_mheap_t mdp = NULL;
   if ((mdp =__mmalloc_default_mdp)){
     while(mdp){
       if(mdp->fd < 0)
@@ -152,10 +141,10 @@ static void mmalloc_fork_child(void)
 }
 
 /* Initialize the default malloc descriptor. */
-void mmalloc_preinit(void)
+void *mmalloc_preinit(void)
 {
   int res;
-  if (!__mmalloc_default_mdp) {
+  if (__mmalloc_default_mdp == NULL) {
     unsigned long mask = ~((unsigned long)getpagesize() - 1);
     void *addr = (void*)(((unsigned long)sbrk(0) + HEAP_OFFSET) & mask);
     __mmalloc_default_mdp = mmalloc_attach(-1, addr);
@@ -166,6 +155,8 @@ void mmalloc_preinit(void)
       THROWF(system_error,0,"xbt_os_thread_atfork() failed: return value %d",res);
   }
   xbt_assert(__mmalloc_default_mdp != NULL);
+
+  return __mmalloc_default_mdp;
 }
 
 void mmalloc_postexit(void)
@@ -175,19 +166,15 @@ void mmalloc_postexit(void)
   mmalloc_detach_no_free(__mmalloc_default_mdp);
 }
 
-int mmalloc_compare_heap(void *h1, void *h2, void *std_heap_addr){
+int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
 
-  if(h1 == NULL && h2 == NULL){
+  if(mdp1 == NULL && mdp2 == NULL){
     XBT_DEBUG("Malloc descriptors null");
     return 0;
   }
 
   /* Heapstats */
 
-  struct mdesc *mdp1, *mdp2;
-  mdp1 = MD_TO_MDP(h1);
-  mdp2 = MD_TO_MDP(h2);
-
   int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
 
   return (errors > 0);
@@ -558,8 +545,17 @@ int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap
 }
 
  
-void mmalloc_display_info_heap(void *h){
+void mmalloc_display_info_heap(xbt_mheap_t h){
 
 }  
+
+/* Useless prototype to make gcc happy */
+void *valloc(size_t size);
+
+void *valloc(size_t size)
+{ //FIXME: won't work
+  return mvalloc(NULL, size);
+}
+
   
 
index a3d29c4..a5a0192 100644 (file)
@@ -100,9 +100,8 @@ static void *morecore(struct mdesc *mdp, size_t size)
 
 /* Allocate memory from the heap.  */
 
-void *mmalloc(void *md, size_t size)
+void *mmalloc(xbt_mheap_t mdp, size_t size)
 {
-  struct mdesc *mdp;
   void *result;
   size_t block, blocks, lastblocks, start;
   register size_t i;
@@ -115,7 +114,6 @@ void *mmalloc(void *md, size_t size)
   if (size == 0)
     size = 1;
 
-  mdp = MD_TO_MDP(md);
 //  printf("(%s) Mallocing %d bytes on %p (default: %p)...",xbt_thread_self_name(),size,mdp,__mmalloc_default_mdp);fflush(stdout);
 
   if (!(mdp->flags & MMALLOC_INITIALIZED)) {
@@ -160,7 +158,7 @@ void *mmalloc(void *md, size_t size)
       /* No free fragments of the desired size, so get a new block
          and break it into fragments, returning the first.  */
       //printf("(%s) No free fragment...",xbt_thread_self_name());
-      result = mmalloc(md, BLOCKSIZE);
+      result = mmalloc(mdp, BLOCKSIZE);
       //printf("(%s) Fragment: %p...",xbt_thread_self_name(),result);
       if (result == NULL) {
         return (NULL);
index f475076..5c7fb24 100644 (file)
@@ -9,17 +9,15 @@
 
 #include "mmprivate.h"
 
-void *mmemalign(void *md, size_t alignment, size_t size)
+void *mmemalign(xbt_mheap_t mdp, size_t alignment, size_t size)
 {
   void *result;
   unsigned long int adj;
   struct alignlist *l;
-  struct mdesc *mdp;
 
-  if ((result = mmalloc(md, size + alignment - 1)) != NULL) {
+  if ((result = mmalloc(mdp, size + alignment - 1)) != NULL) {
     adj = RESIDUAL(result, alignment);
     if (adj != 0) {
-      mdp = MD_TO_MDP(md);
       for (l = mdp->aligned_blocks; l != NULL; l = l->next) {
         if (l->aligned == NULL) {
           /* This slot is free.  Use it.  */
@@ -27,9 +25,9 @@ void *mmemalign(void *md, size_t alignment, size_t size)
         }
       }
       if (l == NULL) {
-        l = (struct alignlist *) mmalloc(md, sizeof(struct alignlist));
+        l = (struct alignlist *) mmalloc(mdp, sizeof(struct alignlist));
         if (l == NULL) {
-          mfree(md, result);
+          mfree(mdp, result);
           return (NULL);
         }
         l->next = mdp->aligned_blocks;
index 4c9dbfd..123b627 100644 (file)
@@ -200,8 +200,6 @@ struct mdesc {
 
 };
 
-int mmalloc_compare_heap(void *h1, void *h2, void *std_heap_addr);
-
 int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr);
 
 void mmalloc_display_info(void *h);
@@ -225,12 +223,6 @@ extern struct mdesc *__mmalloc_default_mdp;
 
 extern struct mdesc *__mmalloc_create_default_mdp(void);
 
-/* Grow or shrink a contiguous mapped region using mmap().
-   Works much like sbrk(), only faster */
-
-extern void *__mmalloc_mmap_morecore(struct mdesc *mdp, int size);
-
-
 /* Remap a mmalloc region that was previously mapped. */
 
 extern void *__mmalloc_remap_core(struct mdesc *mdp);
@@ -240,28 +232,11 @@ extern void *__mmalloc_remap_core(struct mdesc *mdp);
     like sbrk(), but using mmap(). */
 extern void *mmorecore(struct mdesc *mdp, int size);
 
-/* Macro to convert from a user supplied malloc descriptor to pointer to the
-   internal malloc descriptor.  If the user supplied descriptor is NULL, then
-   use the default internal version, initializing it if necessary.  Otherwise
-   just cast the user supplied version (which is void *) to the proper type
-   (struct mdesc *). */
-
-#define MD_TO_MDP(md) \
-  ((md) == NULL \
-   ? __mmalloc_default_mdp  \
-   : (struct mdesc *) (md))
-
-/* Thread-safety (if the sem is already created)*/
-#define LOCK(md)                                        \
-  do {\
-    struct mdesc *lock_local_mdp = MD_TO_MDP(md);       \
-    sem_wait(&lock_local_mdp->sem);     \
-  } while (0)
-
-#define UNLOCK(md)                                        \
-  do {                                                  \
-    struct mdesc *unlock_local_mdp = MD_TO_MDP(md);       \
-    sem_post(&unlock_local_mdp->sem);     \
-  } while (0)
+/* Thread-safety (if the sem is already created) FIXME: KILLIT*/
+#define LOCK(mdp)                                        \
+  sem_wait(&mdp->sem)
+
+#define UNLOCK(mdp)                                        \
+    sem_post(&mdp->sem)
 
 #endif                          /* __MMPRIVATE_H */
index 9b0e907..9d20e03 100644 (file)
    new region.  This module has incestuous knowledge of the
    internals of both mfree and mmalloc. */
 
-void *mrealloc(void *md, void *ptr, size_t size)
+void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size)
 {
-  struct mdesc *mdp;
   void *result;
   int type;
   size_t block, blocks, oldlimit;
 
   if (size == 0) {
-    mfree(md, ptr);
-    return (mmalloc(md, 0));
+    mfree(mdp, ptr);
+    return (mmalloc(mdp, 0));
   } else if (ptr == NULL) {
-    return (mmalloc(md, size));
+    return (mmalloc(mdp, size));
   }
 
-  mdp = MD_TO_MDP(md);
 
   //printf("(%s)realloc %p to %d...",xbt_thread_self_name(),ptr,(int)size);
 
   if ((char *) ptr < (char *) mdp->heapbase || BLOCK(ptr) > mdp->heapsize) {
     printf
         ("FIXME. Ouch, this pointer is not mine, refusing to proceed (another solution would be to malloc it instead of reallocing it, see source code)\n");
-    result = mmalloc(md, size);
+    result = mmalloc(mdp, size);
     abort();
     return result;
   }
@@ -54,10 +52,10 @@ void *mrealloc(void *md, void *ptr, size_t size)
     /* Maybe reallocate a large block to a small fragment.  */
     if (size <= BLOCKSIZE / 2) {
       //printf("(%s) alloc large block...",xbt_thread_self_name());
-      result = mmalloc(md, size);
+      result = mmalloc(mdp, size);
       if (result != NULL) {
         memcpy(result, ptr, size);
-        mfree(md, ptr);
+        mfree(mdp, ptr);
         return (result);
       }
     }
@@ -73,7 +71,7 @@ void *mrealloc(void *md, void *ptr, size_t size)
           = mdp->heapinfo[block].busy.info.block.size - blocks;
       mdp->heapinfo[block].busy.info.block.size = blocks;
       mdp->heapinfo[block].busy.info.block.busy_size = size;
-      mfree(md, ADDRESS(block + blocks));
+      mfree(mdp, ADDRESS(block + blocks));
       result = ptr;
     } else if (blocks == mdp->heapinfo[block].busy.info.block.size) {
       /* No size change necessary.  */
@@ -86,11 +84,11 @@ void *mrealloc(void *md, void *ptr, size_t size)
       /* Prevent free from actually returning memory to the system.  */
       oldlimit = mdp->heaplimit;
       mdp->heaplimit = 0;
-      mfree(md, ptr);
+      mfree(mdp, ptr);
       mdp->heaplimit = oldlimit;
-      result = mmalloc(md, size);
+      result = mmalloc(mdp, size);
       if (result == NULL) {
-        mmalloc(md, blocks * BLOCKSIZE);
+        mmalloc(mdp, blocks * BLOCKSIZE);
         return (NULL);
       }
       if (ptr != result)
@@ -110,12 +108,12 @@ void *mrealloc(void *md, void *ptr, size_t size)
          and copy the lesser of the new size and the old. */
       //printf("(%s) new size is different...",xbt_thread_self_name());
 
-      result = mmalloc(md, size);
+      result = mmalloc(mdp, size);
       if (result == NULL)
         return (NULL);
 
       memcpy(result, ptr, MIN(size, (size_t) 1 << type));
-      mfree(md, ptr);
+      mfree(mdp, ptr);
     }
     break;
   }
index 93caf73..c940ee9 100644 (file)
@@ -21,19 +21,12 @@ static size_t cache_pagesize;
 extern int getpagesize PARAMS((void));
 #endif
 
-void *mvalloc(void *md, size_t size)
+void *mvalloc(xbt_mheap_t mdp, size_t size)
 {
   if (cache_pagesize == 0) {
     cache_pagesize = getpagesize();
   }
 
-  return (mmemalign(md, cache_pagesize, size));
+  return (mmemalign(mdp, cache_pagesize, size));
 }
 
-/* Useless prototype to make gcc happy */
-void *valloc(size_t size);
-
-void *valloc(size_t size)
-{
-  return mvalloc(NULL, size);
-}
index 2e2d829..9e0892f 100644 (file)
@@ -31,7 +31,7 @@ void xbt_trp_postexit(void);
 void xbt_datadesc_preinit(void);
 void xbt_datadesc_postexit(void);
 
-void mmalloc_preinit(void);
+void *mmalloc_preinit(void);
 void mmalloc_postexit(void);