Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
.
[simgrid.git] / src / xbt / mmalloc / mrealloc.c
index 866abcf..7e83e20 100644 (file)
@@ -1,26 +1,14 @@
 /* Change the size of a block allocated by `mmalloc'.
    Copyright 1990, 1991 Free Software Foundation
-                 Written May 1989 by Mike Haertel.
+                 Written May 1989 by Mike Haertel. */
 
-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.
+/* Copyright (c) 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
 
-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.
+/* 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. */
 
-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.
-
-   The author may be reached (Email) at the address mike@ai.mit.edu,
-   or (US mail) as Mike Haertel c/o Free Software Foundation. */
-
-#include <string.h>    /* Prototypes for memcpy, memmove, memset, etc */
+#include <string.h>             /* Prototypes for memcpy, memmove, memset, etc */
 
 #include "mmprivate.h"
 
@@ -31,131 +19,109 @@ Boston, MA 02111-1307, USA.
    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(void *md, void *ptr, size_t size)
 {
   struct mdesc *mdp;
-  voidresult;
+  void *result;
   int type;
   size_t block, blocks, oldlimit;
 
-  if (size == 0)
-    {
-      mfree (md, ptr);
-      return (mmalloc (md, 0));
+  if (size == 0) {
+    mfree(md, ptr);
+    return (mmalloc(md, 0));
+  } else if (ptr == NULL) {
+    return (mmalloc(md, 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. I will malloc it instead of reallocing it. (please report this bug)\n");
+    result = mmalloc(md, size);
+    abort();
+    return result;
+  }
+
+  if (mdp->mrealloc_hook != NULL) {
+    return mdp->mrealloc_hook(md, ptr, size);
+  }
+
+  block = BLOCK(ptr);
+
+  type = mdp->heapinfo[block].busy.type;
+  switch (type) {
+  case 0:
+    /* 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);
+      if (result != NULL) {
+        memcpy(result, ptr, size);
+        mfree(md, ptr);
+        return (result);
+      }
     }
-  else if (ptr == NULL)
-    {
-      return (mmalloc (md, size));
-    }
-
-  mdp = MD_TO_MDP (md);
 
-  if (mdp -> mrealloc_hook != NULL)
-    {
-      return ((*mdp -> mrealloc_hook) (md, ptr, size));
+    /* The new size is a large allocation as well;
+       see if we can hold it in place. */
+    blocks = BLOCKIFY(size);
+    if (blocks < mdp->heapinfo[block].busy.info.block.size) {
+      /* The new size is smaller; return excess memory to the free list. */
+      //printf("(%s) return excess memory...",xbt_thread_self_name());
+      mdp->heapinfo[block + blocks].busy.type = 0;
+      mdp->heapinfo[block + blocks].busy.info.block.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));
+      result = ptr;
+    } else if (blocks == mdp->heapinfo[block].busy.info.block.size) {
+      /* No size change necessary.  */
+      result = ptr;
+    } else {
+      /* Won't fit, so allocate a new region that will.
+         Free the old region first in case there is sufficient
+         adjacent free space to grow without moving. */
+      blocks = mdp->heapinfo[block].busy.info.block.size;
+      /* Prevent free from actually returning memory to the system.  */
+      oldlimit = mdp->heaplimit;
+      mdp->heaplimit = 0;
+      mfree(md, ptr);
+      mdp->heaplimit = oldlimit;
+      result = mmalloc(md, size);
+      if (result == NULL) {
+        mmalloc(md, blocks * BLOCKSIZE);
+        return (NULL);
+      }
+      if (ptr != result)
+        memmove(result, ptr, blocks * BLOCKSIZE);
     }
-
-  block = BLOCK (ptr);
-
-  type = mdp -> heapinfo[block].busy.type;
-  switch (type)
-    {
-    case 0:
-      /* Maybe reallocate a large block to a small fragment.  */
-      if (size <= BLOCKSIZE / 2)
-       {
-         result = mmalloc (md, size);
-         if (result != NULL)
-           {
-             memcpy (result, ptr, size);
-             mfree (md, ptr);
-             return (result);
-           }
-       }
-
-      /* The new size is a large allocation as well;
-        see if we can hold it in place. */
-      blocks = BLOCKIFY (size);
-      if (blocks < mdp -> heapinfo[block].busy.info.size)
-       {
-         /* The new size is smaller; return excess memory to the free list. */
-         mdp -> heapinfo[block + blocks].busy.type = 0;
-         mdp -> heapinfo[block + blocks].busy.info.size
-           = mdp -> heapinfo[block].busy.info.size - blocks;
-         mdp -> heapinfo[block].busy.info.size = blocks;
-         mfree (md, ADDRESS (block + blocks));
-         result = ptr;
-       }
-      else if (blocks == mdp -> heapinfo[block].busy.info.size)
-       {
-         /* No size change necessary.  */
-         result = ptr;
-       }
-      else
-       {
-         /* Won't fit, so allocate a new region that will.
-            Free the old region first in case there is sufficient
-            adjacent free space to grow without moving. */
-         blocks = mdp -> heapinfo[block].busy.info.size;
-         /* Prevent free from actually returning memory to the system.  */
-         oldlimit = mdp -> heaplimit;
-         mdp -> heaplimit = 0;
-         mfree (md, ptr);
-         mdp -> heaplimit = oldlimit;
-         result = mmalloc (md, size);
-         if (result == NULL)
-           {
-             mmalloc (md, blocks * BLOCKSIZE);
-             return (NULL);
-           }
-         if (ptr != result)
-           {
-             memmove (result, ptr, blocks * BLOCKSIZE);
-           }
-       }
-      break;
-
-    default:
-      /* Old size is a fragment; type is logarithm
-        to base two of the fragment size.  */
-      if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type))
-       {
-         /* The new size is the same kind of fragment.  */
-         result = ptr;
-       }
-      else
-       {
-         /* The new size is different; allocate a new space,
-            and copy the lesser of the new size and the old. */
-         result = mmalloc (md, size);
-         if (result == NULL)
-           {
-             return (NULL);
-           }
-         memcpy (result, ptr, MIN (size, (size_t) 1 << type));
-         mfree (md, ptr);
-       }
-      break;
+    break;
+
+  default:
+    /* Old size is a fragment; type is logarithm
+       to base two of the fragment size.  */
+    if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type)) {
+      /* The new size is the same kind of fragment.  */
+      //printf("(%s) new size is same kind of fragment...",xbt_thread_self_name());
+      result = ptr;
+    } else {
+      /* The new size is different; allocate a new space,
+         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);
+      if (result == NULL)
+        return (NULL);
+
+      memcpy(result, ptr, MIN(size, (size_t) 1 << type));
+      mfree(md, ptr);
     }
-
-  return (result);
-}
-
-/* Useless prototype to make gcc happy */
-void *realloc (void *ptr, size_t size);
-
-/* When using this package, provide a version of malloc/realloc/free built
-   on top of it, so that if we use the default sbrk() region we will not
-   collide with another malloc package trying to do the same thing, if
-   the application contains any "hidden" calls to malloc/realloc/free (such
-   as inside a system library). */
-
-void *
-realloc (void *ptr, size_t size)
-{
-  void* result;
-
-  result = mrealloc (NULL, ptr, size);
+    break;
+  }
+  //printf("(%s) Done reallocing: %p\n",xbt_thread_self_name(),result);fflush(stdout);
   return (result);
 }