-/* 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 <sys/types.h>
#include <fcntl.h> /* After sys/types.h, at least for dpx/2. */
#include <sys/stat.h>
#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
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;
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++;
}
}
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. */
struct mdesc *mdp = md;
if(--mdp->refcount == 0){
- LOCK(mdp) ;
- sem_destroy(&mdp->sem);
+ pthread_mutex_destroy(&mdp->mutex);
}
}
{
int res;
if (__mmalloc_default_mdp == NULL) {
+ 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
}
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;
}
// 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;
}
}
+
+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.");
+ }
+ }
+ }
+}