Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
please codacy
[simgrid.git] / src / xbt / mmalloc / mm_module.c
index 7cfde64..eac80c8 100644 (file)
@@ -1,5 +1,12 @@
-/* Initialization for access to a mmap'd malloc managed region.
-   Copyright 1992, 2000 Free Software Foundation, Inc.
+/* Initialization for acces s to a mmap'd malloc managed region. */
+
+/* Copyright (c) 2012-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* 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. */
+
+/* Copyright 1992, 2000 Free Software Foundation, Inc.
 
    Contributed by Fred Fish at Cygnus Support.   fnf@cygnus.com
 
    not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-/* Copyright (c) 2012-2014. The SimGrid Team.
- * All rights reserved.                                                     */
-
-/* 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. */
-
+#include "src/internal_config.h"
 #include <sys/types.h>
 #include <fcntl.h>              /* After sys/types.h, at least for dpx/2.  */
 #include <sys/stat.h>
 #include <string.h>
-#ifdef HAVE_UNISTD_H
+#if HAVE_UNISTD_H
 #include <unistd.h>             /* Prototypes for lseek */
 #endif
 #include "mmprivate.h"
 #include "xbt/ex.h"
-#include "xbt_modinter.h" /* declarations of mmalloc_preinit and friends that live here */
+#include "src/xbt_modinter.h" /* declarations of mmalloc_preinit and friends that live here */
 
 #ifndef SEEK_SET
 #define SEEK_SET 0
@@ -46,7 +48,7 @@
    If FD is a valid file descriptor for an open file then data for the
    mmalloc managed region is mapped to that file, otherwise an anonymous
    map is used if supported by the underlying OS. In case of running in
-   an OS without support of anonymous mappings then "/dev/zero" is used 
+   an OS without support of anonymous mappings then "/dev/zero" is used
    and in both cases the data will not exist in any filesystem object.
 
    If the open file corresponding to FD is from a previous use of
@@ -56,8 +58,8 @@
    the current process as the process that created the file (ignoring
    the BASEADDR parameter).
 
-   For non valid FDs or empty files ones the mapping is established 
-   starting at the specified address BASEADDR in the process address 
+   For non valid FDs or empty files ones the mapping is established
+   starting at the specified address BASEADDR in the process address
    space.
 
    The provided BASEADDR should be choosed carefully in order to avoid
    On failure returns NULL. */
 
 xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr)
+{
+  return xbt_mheap_new_options(fd, baseaddr, 0);
+}
+
+xbt_mheap_t xbt_mheap_new_options(int fd, void *baseaddr, int options)
 {
   struct mdesc mtemp;
   xbt_mheap_t mdp;
@@ -131,7 +138,7 @@ xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr)
         mdptr = (struct mdesc *) newmd.base;
         mdptr->fd = fd;
         if(!mdptr->refcount){
-          sem_init(&mdptr->sem, 0, 1);
+          pthread_mutex_init(&mdptr->mutex, NULL);
           mdptr->refcount++;
         }
       }
@@ -168,15 +175,15 @@ xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr)
   mdp->base = mdp->breakval = mdp->top = baseaddr;
   mdp->next_mdesc = NULL;
   mdp->refcount = 1;
-  
+  mdp->options = options;
+
   /* If we have not been passed a valid open file descriptor for the file
      to map to, then we go for an anonymous map */
 
   if (mdp->fd < 0){
     mdp->flags |= MMALLOC_ANONYMOUS;
   }
-  sem_init(&mdp->sem, 0, 1);
-  
+  pthread_mutex_init(&mdp->mutex, NULL);
   /* 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. */
 
@@ -192,7 +199,7 @@ xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr)
     abort();
   }
 
-  /* Add the new heap to the linked list of heaps attached by mmalloc */  
+  /* Add the new heap to the linked list of heaps attached by mmalloc */
   if(__mmalloc_default_mdp){
     mdp = __mmalloc_default_mdp;
     while(mdp->next_mdesc)
@@ -218,8 +225,7 @@ void xbt_mheap_destroy_no_free(xbt_mheap_t md)
   struct mdesc *mdp = md;
 
   if(--mdp->refcount == 0){
-    LOCK(mdp) ;
-    sem_destroy(&mdp->sem);
+    pthread_mutex_destroy(&mdp->mutex);
   }
 }
 
@@ -321,25 +327,21 @@ static void mmalloc_fork_child(void)
 /* Initialize the default malloc descriptor. */
 void *mmalloc_preinit(void)
 {
-  int res;
   if (__mmalloc_default_mdp == NULL) {
-    unsigned long mask = ~((unsigned long)getpagesize() - 1);
+    if(!xbt_pagesize)
+      xbt_pagesize = getpagesize();
+    unsigned long mask = ~((unsigned long)xbt_pagesize - 1);
     void *addr = (void*)(((unsigned long)sbrk(0) + HEAP_OFFSET) & mask);
-    __mmalloc_default_mdp = xbt_mheap_new(-1, addr);
+    __mmalloc_default_mdp = xbt_mheap_new_options(-1, addr, XBT_MHEAP_OPTION_MEMSET);
     /* Fixme? only the default mdp in protected against forks */
     // 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);
+    int 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);
   }
   xbt_assert(__mmalloc_default_mdp != NULL);
 
-#if defined(HAVE_GNU_LD) && defined(MMALLOC_WANT_OVERRIDE_LEGACY)
-  mm_gnuld_legacy_init();
-#endif
-
   return __mmalloc_default_mdp;
 }
 
@@ -350,37 +352,70 @@ void mmalloc_postexit(void)
   // xbt_mheap_destroy_no_free(__mmalloc_default_mdp);
 }
 
-size_t mmalloc_get_bytes_used(xbt_mheap_t heap){
-  int i = 0, j = 0;
+// This is the underlying implementation of mmalloc_get_bytes_used_remote.
+// Is it used directly in order to evaluate the bytes used from a different
+// process.
+size_t mmalloc_get_bytes_used_remote(size_t heaplimit, const malloc_info* heapinfo)
+{
   int bytes = 0;
-  
-  while(i<=((struct mdesc *)heap)->heaplimit){
-    if(((struct mdesc *)heap)->heapinfo[i].type == 0){
-      if(((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size > 0)
-        bytes += ((struct mdesc *)heap)->heapinfo[i].busy_block.busy_size;
-     
-    }else if(((struct mdesc *)heap)->heapinfo[i].type > 0){
-      for(j=0; j < (size_t) (BLOCKSIZE >> ((struct mdesc *)heap)->heapinfo[i].type); j++){
-        if(((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j] > 0)
-          bytes += ((struct mdesc *)heap)->heapinfo[i].busy_frag.frag_size[j];
+  for (size_t i=0; i < heaplimit; ++i){
+    if (heapinfo[i].type == MMALLOC_TYPE_UNFRAGMENTED){
+      if (heapinfo[i].busy_block.busy_size > 0)
+        bytes += heapinfo[i].busy_block.busy_size;
+    } else if (heapinfo[i].type > 0) {
+      for (size_t j=0; j < (size_t) (BLOCKSIZE >> heapinfo[i].type); j++){
+        if(heapinfo[i].busy_frag.frag_size[j] > 0)
+          bytes += heapinfo[i].busy_frag.frag_size[j];
       }
     }
-    i++; 
   }
-
   return bytes;
 }
 
+size_t mmalloc_get_bytes_used(const xbt_mheap_t heap){
+  const struct mdesc* heap_data = (const struct mdesc *) heap;
+  return mmalloc_get_bytes_used_remote(heap_data->heaplimit, heap_data->heapinfo);
+}
+
 ssize_t mmalloc_get_busy_size(xbt_mheap_t heap, void *ptr){
 
   ssize_t block = ((char*)ptr - (char*)(heap->heapbase)) / BLOCKSIZE + 1;
-  if(heap->heapinfo[block].type == -1)
+  if(heap->heapinfo[block].type < 0)
     return -1;
-  else if(heap->heapinfo[block].type == 0)
+  else if(heap->heapinfo[block].type == MMALLOC_TYPE_UNFRAGMENTED)
     return heap->heapinfo[block].busy_block.busy_size;
   else{
     ssize_t frag = ((uintptr_t) (ADDR2UINT (ptr) % (BLOCKSIZE))) >> heap->heapinfo[block].type;
     return heap->heapinfo[block].busy_frag.frag_size[frag];
   }
-    
+
+}
+
+void mmcheck(xbt_mheap_t heap) {return;
+  if (!heap->heapinfo)
+    return;
+  malloc_info* heapinfo = NULL;
+  for (size_t i=1; i < heap->heaplimit; i += mmalloc_get_increment(heapinfo)) {
+    heapinfo = heap->heapinfo + i;
+    switch (heapinfo->type) {
+    case MMALLOC_TYPE_HEAPINFO:
+    case MMALLOC_TYPE_FREE:
+      if (heapinfo->free_block.size==0) {
+        xbt_die("Block size == 0");
+      }
+      break;
+    case MMALLOC_TYPE_UNFRAGMENTED:
+      if (heapinfo->busy_block.size==0) {
+        xbt_die("Block size == 0");
+      }
+      if (heapinfo->busy_block.busy_size==0 && heapinfo->busy_block.size!=0) {
+        xbt_die("Empty busy block");
+      }
+      break;
+    default:
+      if (heapinfo->type<0) {
+        xbt_die("Unkown mmalloc block type.");
+      }
+    }
+  }
 }