Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : getter function for chunks used in heap
[simgrid.git] / src / xbt / mmalloc / mm_module.c
index 7aea0c1..de1942a 100644 (file)
@@ -3,22 +3,22 @@
 
    Contributed by Fred Fish at Cygnus Support.   fnf@cygnus.com
 
-This file is part of the GNU C Library.
+   This file is part of the GNU C Library.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <sys/types.h>
 #include <fcntl.h>              /* After sys/types.h, at least for dpx/2.  */
@@ -64,7 +64,7 @@ Boston, MA 02111-1307, USA.  */
 
    On failure returns NULL. */
 
-xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
+xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr)
 {
   struct mdesc mtemp;
   xbt_mheap_t mdp;
@@ -83,67 +83,68 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
       return (NULL);
 
     else if (sbuf.st_size > 0) {
-       /* We were given an valid file descriptor on an open file, so try to remap
-          it into the current process at the same address to which it was previously
-          mapped. It naturally have to pass some sanity checks for that.
-
-          Note that we have to update the file descriptor number in the malloc-
-          descriptor read from the file to match the current valid one, before
-          trying to map the file in, and again after a successful mapping and
-          after we've switched over to using the mapped in malloc descriptor
-          rather than the temporary one on the stack.
-
-          Once we've switched over to using the mapped in malloc descriptor, we
-          have to update the pointer to the morecore function, since it almost
-          certainly will be at a different address if the process reusing the
-          mapped region is from a different executable.
-
-          Also note that if the heap being remapped previously used the mmcheckf()
-          routines, we need to update the hooks since their target functions
-          will have certainly moved if the executable has changed in any way.
-          We do this by calling mmcheckf() internally.
-
-          Returns a pointer to the malloc descriptor if successful, or NULL if
-          unsuccessful for some reason. */
-
-         struct mdesc mtemp;
-         struct mdesc *mdp = NULL, *mdptemp = NULL;
-
-         if (lseek(fd, 0L, SEEK_SET) != 0)
-           return NULL;
-         if (read(fd, (char *) &mtemp, sizeof(mtemp)) != sizeof(mtemp))
-           return NULL;
-         if (mtemp.headersize != sizeof(mtemp))
-           return NULL;
-         if (strcmp(mtemp.magic, MMALLOC_MAGIC) != 0)
-           return NULL;
-         if (mtemp.version > MMALLOC_VERSION)
-           return NULL;
-
-         mtemp.fd = fd;
-         if (__mmalloc_remap_core(&mtemp) == mtemp.base) {
-           mdp = (struct mdesc *) mtemp.base;
-           mdp->fd = fd;
-           if(!mdp->refcount){
-             sem_init(&mdp->sem, 1, 1);
-             mdp->refcount++;
-           }
-         }
-
-         /* Add the new heap to the linked list of heaps attached by mmalloc */
-         mdptemp = __mmalloc_default_mdp;
-         while(mdptemp->next_mdesc)
-           mdptemp = mdptemp->next_mdesc;
-
-         LOCK(mdptemp);
-           mdptemp->next_mdesc = mdp;
-         UNLOCK(mdptemp);
-
-         return (mdp);
+      /* We were given an valid file descriptor on an open file, so try to remap
+         it into the current process at the same address to which it was previously
+         mapped. It naturally have to pass some sanity checks for that.
+
+         Note that we have to update the file descriptor number in the malloc-
+         descriptor read from the file to match the current valid one, before
+         trying to map the file in, and again after a successful mapping and
+         after we've switched over to using the mapped in malloc descriptor
+         rather than the temporary one on the stack.
+
+         Once we've switched over to using the mapped in malloc descriptor, we
+         have to update the pointer to the morecore function, since it almost
+         certainly will be at a different address if the process reusing the
+         mapped region is from a different executable.
+
+         Also note that if the heap being remapped previously used the mmcheckf()
+         routines, we need to update the hooks since their target functions
+         will have certainly moved if the executable has changed in any way.
+         We do this by calling mmcheckf() internally.
+
+         Returns a pointer to the malloc descriptor if successful, or NULL if
+         unsuccessful for some reason. */
+
+      struct mdesc newmd;
+      struct mdesc *mdptr = NULL, *mdptemp = NULL;
+
+      if (lseek(fd, 0L, SEEK_SET) != 0)
+        return NULL;
+      if (read(fd, (char *) &newmd, sizeof(newmd)) != sizeof(newmd))
+        return NULL;
+      if (newmd.headersize != sizeof(newmd))
+        return NULL;
+      if (strcmp(newmd.magic, MMALLOC_MAGIC) != 0)
+        return NULL;
+      if (newmd.version > MMALLOC_VERSION)
+        return NULL;
+
+      newmd.fd = fd;
+      if (__mmalloc_remap_core(&newmd) == newmd.base) {
+        mdptr = (struct mdesc *) newmd.base;
+        mdptr->fd = fd;
+        if(!mdptr->refcount){
+          sem_init(&mdptr->sem, 0, 1);
+          mdptr->refcount++;
+        }
+      }
+
+      /* Add the new heap to the linked list of heaps attached by mmalloc */
+      mdptemp = __mmalloc_default_mdp;
+      while(mdptemp->next_mdesc)
+        mdptemp = mdptemp->next_mdesc;
+
+      LOCK(mdptemp);
+      mdptemp->next_mdesc = mdptr;
+      UNLOCK(mdptemp);
+
+      return mdptr;
     }
   }
 
-  /* If the user provided NULL BASEADDR then fail */
+  /* NULL is not a valid baseaddr as we cannot map anything there.
+     C'mon, user. Think! */
   if (baseaddr == NULL)
     return (NULL);
 
@@ -167,10 +168,8 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
 
   if (mdp->fd < 0){
     mdp->flags |= MMALLOC_ANONYMOUS;
-    sem_init(&mdp->sem, 0, 1);
-  }else{
-    sem_init(&mdp->sem, 1, 1);
   }
+  sem_init(&mdp->sem, 0, 1);
   
   /* If we have not been passed a valid open file descriptor for the file
      to map to, then open /dev/zero and use that to map to. */
@@ -183,7 +182,8 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
   if ((mbase = mmorecore(mdp, sizeof(mtemp))) != NULL) {
     memcpy(mbase, mdp, sizeof(mtemp));
   } else {
-    THROWF(system_error,0,"morecore failed to get some memory!");
+    fprintf(stderr, "morecore failed to get some more memory!\n");
+    abort();
   }
 
   /* Add the new heap to the linked list of heaps attached by mmalloc */  
@@ -193,7 +193,7 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
       mdp = mdp->next_mdesc;
 
     LOCK(mdp);
-      mdp->next_mdesc = (struct mdesc *)mbase;
+    mdp->next_mdesc = (struct mdesc *)mbase;
     UNLOCK(mdp);
   }
 
@@ -207,7 +207,7 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
  * 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(xbt_mheap_t md)
+void xbt_mheap_destroy_no_free(xbt_mheap_t md)
 {
   struct mdesc *mdp = md;
 
@@ -218,20 +218,20 @@ void mmalloc_detach_no_free(xbt_mheap_t md)
 }
 
 /** Terminate access to a mmalloc managed region by unmapping all memory pages
-   associated with the region, and closing the file descriptor if it is one
-   that we opened.
+    associated with the region, and closing the file descriptor if it is one
+    that we opened.
 
-   Returns NULL on success.
+    Returns NULL on success.
 
-   Returns the malloc descriptor on failure, which can subsequently be used
-   for further action, such as obtaining more information about the nature of
-   the failure by examining the preserved errno value.
+    Returns the malloc descriptor on failure, which can subsequently be used
+    for further action, such as obtaining more information about the nature of
+    the failure.
 
-   Note that the malloc descriptor that we are using is currently located in
-   region we are about to unmap, so we first make a local copy of it on the
-   stack and use the copy. */
+    Note that the malloc descriptor that we are using is currently located in
+    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(xbt_mheap_t mdp)
+void *xbt_mheap_destroy(xbt_mheap_t mdp)
 {
   struct mdesc mtemp, *mdptemp;
 
@@ -243,15 +243,13 @@ void *mmalloc_detach(xbt_mheap_t mdp)
 
     mdptemp->next_mdesc = mdp->next_mdesc;
 
-    mmalloc_detach_no_free(mdp);
+    xbt_mheap_destroy_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. */
 
-    if ((mmorecore(&mtemp,
-                        (char *) mtemp.base - (char *) mtemp.breakval)) ==
-        NULL) {
+    if (mmorecore(&mtemp, (char *)mtemp.base - (char *)mtemp.breakval) == NULL) {
       /* Deallocating failed.  Update the original malloc descriptor
          with any changes */
       *mdp = mtemp;
@@ -314,8 +312,6 @@ static void mmalloc_fork_child(void)
   }
 }
 
-
-
 /* Initialize the default malloc descriptor. */
 void *mmalloc_preinit(void)
 {
@@ -323,10 +319,12 @@ void *mmalloc_preinit(void)
   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);
+    __mmalloc_default_mdp = xbt_mheap_new(-1, addr);
     /* Fixme? only the default mdp in protected against forks */
-    res = xbt_os_thread_atfork(mmalloc_fork_prepare,
-                              mmalloc_fork_parent, mmalloc_fork_child);
+    // This is mandated to protect the mmalloced areas through forks. Think of tesh.
+    // Nah, removing the mutex isn't a good idea either for tesh
+    res = xbt_os_thread_atfork(mmalloc_fork_prepare,  
+                               mmalloc_fork_parent, mmalloc_fork_child);
     if (res != 0)
       THROWF(system_error,0,"xbt_os_thread_atfork() failed: return value %d",res);
   }
@@ -339,5 +337,9 @@ 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);
-  mmalloc_detach_no_free(__mmalloc_default_mdp);
+  xbt_mheap_destroy_no_free(__mmalloc_default_mdp);
+}
+
+size_t mmalloc_get_chunks_used(xbt_mheap_t heap){
+  return ((struct mdesc *)heap)->heapstats.chunks_used;
 }