Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Disable soft-dirty page tracking by default
[simgrid.git] / src / xbt / mmalloc / mm_module.c
index 06f6266..a2c36cd 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
 
    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;
@@ -162,6 +174,7 @@ 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 */
@@ -317,23 +330,93 @@ void *mmalloc_preinit(void)
 {
   int res;
   if (__mmalloc_default_mdp == NULL) {
-    unsigned long mask = ~((unsigned long)getpagesize() - 1);
+    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 */
-    res = xbt_os_thread_atfork(mmalloc_fork_prepare,  //FIXME: KILLME when things settle a bit
+    // 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);
   }
   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;
 }
 
 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);
-  xbt_mheap_destroy_no_free(__mmalloc_default_mdp);
+  /* Do not destroy the default mdp or ldl won't be able to free the memory it
+   * allocated since we're in memory */
+  // xbt_mheap_destroy_no_free(__mmalloc_default_mdp);
+}
+
+size_t mmalloc_get_bytes_used(xbt_mheap_t heap){
+  int i = 0, j = 0;
+  int bytes = 0;
+  
+  while(i<=((struct mdesc *)heap)->heaplimit){
+    if(((struct mdesc *)heap)->heapinfo[i].type == MMALLOC_TYPE_UNFRAGMENTED){
+      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];
+      }
+    }
+    i++; 
+  }
+
+  return bytes;
+}
+
+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 < 0)
+    return -1;
+  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.");
+      }
+    }
+  }
 }