* device/lib/printfl.c: 13 bytes less __data mem (12 more __idata)
[fw/sdcc] / device / lib / realloc.c
index 54fde7f92f09bfaf164d51317ed4a42e9528df98..4fad06e9b301053f638715aae689acc1e8f2b50d 100644 (file)
@@ -1,9 +1,33 @@
+/*-------------------------------------------------------------------------
+   realloc.c - reallocate allocated memory.
+
+   Copyright (C) 2004 - Maarten Brock, sourceforge.brock@dse.nl
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+-------------------------------------------------------------------------*/
+
 #include <sdcc-lib.h>
 #include <malloc.h>
 #include <string.h>
 
-//--------------------------------------------------------------------
-//Written by Maarten Brock, 2004
+#if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) || defined(SDCC_gbz80)
+  #define CRITICAL critical
+#else
+  #define CRITICAL
+#endif
+
 //--------------------------------------------------------------------
 //realloc function implementation for embedded system
 //Non-ANSI keywords are C51 specific.
@@ -25,10 +49,21 @@ struct _MEMHEADER
 };
 
 #define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+#define MEM(x)      (&x->mem)
 
 #else
 
+#define MEMHEADER   struct MAH// Memory Allocation Header
+
+MEMHEADER
+{
+  MEMHEADER __xdata *  next;
+  unsigned int         len;
+  unsigned char        mem[];
+};
+
 #define HEADER_SIZE sizeof(MEMHEADER)
+#define MEM(x)      (x->mem)
 
 #endif
 
@@ -42,42 +77,61 @@ void xdata * realloc (void * p, size_t size)
 {
   register MEMHEADER xdata * pthis;
   register MEMHEADER xdata * pnew;
+  register void xdata * ret;
 
-  pthis = _sdcc_find_memheader(p);
-  if (pthis)
+  CRITICAL
   {
-    if (size>(0xFFFF-HEADER_SIZE)) return (void xdata *) NULL; //To prevent overflow in next line
-    size += HEADER_SIZE; //We need a memory for header too
+    pthis = _sdcc_find_memheader(p);
+    if (pthis)
+    {
+      if (size > (0xFFFF-HEADER_SIZE))
+      {
+        ret = (void xdata *) NULL; //To prevent overflow in next line
+      }
+      else
+      {
+        size += HEADER_SIZE; //We need a memory for header too
+
+        if ((((unsigned int)pthis->next) - ((unsigned int)pthis)) >= size)
+        {//if spare is more than needed
+          pthis->len = size;
+          ret = p;
+        }
+        else
+        {
+          if ((_sdcc_prev_memheader) &&
+              ((((unsigned int)pthis->next) -
+                ((unsigned int)_sdcc_prev_memheader) -
+                _sdcc_prev_memheader->len) >= size))
+          {
+            pnew = (MEMHEADER xdata * )((char xdata *)_sdcc_prev_memheader + _sdcc_prev_memheader->len);
+            _sdcc_prev_memheader->next = pnew;
 
-    if ((((unsigned int)pthis->next) - ((unsigned int)pthis)) >= size)
-    {//if spare is more than need
-      pthis->len = size;
-      return p;
-    }
+#if _SDCC_MALLOC_TYPE_MLH
+            pthis->next->prev = pnew;
+#endif
 
-    if ((_sdcc_prev_memheader) &&
-        ((((unsigned int)pthis->next) -
-          ((unsigned int)_sdcc_prev_memheader) -
-          _sdcc_prev_memheader->len) >= size))
-    {
-      pnew = (MEMHEADER xdata * )((char xdata *)_sdcc_prev_memheader + _sdcc_prev_memheader->len);
-      _sdcc_prev_memheader->next = pnew;
-      memmove(pnew, pthis, pthis->len);
-      pnew->len = size;
-      return pnew->mem;
+            memmove(pnew, pthis, pthis->len);
+            pnew->len = size;
+            ret = MEM(pnew);
+          }
+          else
+          {
+            ret = malloc(size - HEADER_SIZE);
+            if (ret)
+            {
+              memcpy(ret, MEM(pthis), pthis->len - HEADER_SIZE);
+              free(p);
+            }
+          }
+        }
+      }
     }
-
-    pnew = malloc(size - HEADER_SIZE);
-    if (pnew)
+    else
     {
-      memcpy(pnew, pthis->mem, pthis->len - HEADER_SIZE);
-      free(p);
+      ret = malloc(size);
     }
-    return pnew;
-  }
-  else
-  {
-       return malloc(size);
   }
+  return ret;
 }
 //END OF MODULE