X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Frealloc.c;h=4fad06e9b301053f638715aae689acc1e8f2b50d;hb=ec23c7b6350ed6d5b1593573aa303489894577eb;hp=54fde7f92f09bfaf164d51317ed4a42e9528df98;hpb=36d0b20243251f44573d20e6e012d450ab0df882;p=fw%2Fsdcc diff --git a/device/lib/realloc.c b/device/lib/realloc.c index 54fde7f9..4fad06e9 100644 --- a/device/lib/realloc.c +++ b/device/lib/realloc.c @@ -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 #include #include -//-------------------------------------------------------------------- -//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