From: maartenbrock Date: Tue, 27 Jul 2004 20:03:35 +0000 (+0000) Subject: * added lib/calloc.c, lib/free.c, lib/realloc.c, include/stddef.h X-Git-Url: https://git.gag.com/?p=fw%2Fsdcc;a=commitdiff_plain;h=36d0b20243251f44573d20e6e012d450ab0df882 * added lib/calloc.c, lib/free.c, lib/realloc.c, include/stddef.h * updated lib/malloc.c, lib/libsdcc.lib, lib/Makefile.in, include/malloc.h git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3406 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/device/include/malloc.h b/device/include/malloc.h index 4a1a00ac..6e217a4c 100644 --- a/device/include/malloc.h +++ b/device/include/malloc.h @@ -25,14 +25,14 @@ #ifndef __SDCC51_MALLOC_H #define __SDCC51_MALLOC_H #include - -#ifndef NULL -# define NULL (void *)0 -#endif +#include #if _SDCC_MALLOC_TYPE_MLH -void *malloc (unsigned int); -void free(void *p); + +void * calloc (size_t nmemb, size_t size); +void * malloc (size_t size); +void * realloc (void * ptr, size_t size); +void free (void * ptr); #else @@ -41,22 +41,25 @@ void free(void *p); MEMHEADER { MEMHEADER xdata * next; - MEMHEADER xdata * prev; unsigned int len; - unsigned char mem[1]; + unsigned char mem[]; }; #ifdef SDCC_STACK_AUTO -extern void init_dynamic_memory(MEMHEADER xdata * , unsigned int ) reentrant; -extern void xdata * malloc (unsigned int ) reentrant; -extern void free (void xdata * p) reentrant; +extern void init_dynamic_memory(void xdata * heap, unsigned int size) reentrant; +extern void xdata * calloc (size_t nmemb, size_t size) reentrant; +extern void xdata * malloc (size_t size) reentrant; +extern void xdata * realloc (void * ptr, size_t size) reentrant; +extern void free (void * ptr) reentrant; #else -extern void init_dynamic_memory(MEMHEADER xdata * , unsigned int ); -extern void xdata * malloc (unsigned int ); -extern void free (void xdata * p); +extern void init_dynamic_memory(void xdata * heap, unsigned int size); +extern void xdata * calloc (size_t nmemb, size_t size); +extern void xdata * malloc (size_t size); +extern void xdata * realloc (void * ptr, size_t size); +extern void free (void * ptr); #endif #endif diff --git a/device/include/stddef.h b/device/include/stddef.h new file mode 100644 index 00000000..908b5884 --- /dev/null +++ b/device/include/stddef.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + stddef.h - ANSI functions forward declarations + + Written By - Maarten Brock / sourceforge.brock@dse.nl (June 2004) + + 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 +-------------------------------------------------------------------------*/ + +#ifndef __SDC51_STDDEF_H +#define __SDC51_STDDEF_H 1 + +#ifndef NULL + #define NULL (void *)0 +#endif + +#ifndef _SIZE_T_DEFINED +#define _SIZE_T_DEFINED + typedef unsigned int size_t; +#endif + +#define offsetof(s,m) (size_t)&(((s *)0)->m) + +#endif diff --git a/device/lib/Makefile.in b/device/lib/Makefile.in index 50feb387..d791eedf 100644 --- a/device/lib/Makefile.in +++ b/device/lib/Makefile.in @@ -58,8 +58,10 @@ SOURCES = _atof.c _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \ _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \ _strcspn.c _strlen.c _strncat.c _strncmp.c \ _strncpy.c _strpbrk.c _strrchr.c _strspn.c \ - _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \ - _ulong2fs.c malloc.c serial.c ser_ir.c printfl.c \ + _strstr.c _strtok.c \ + _uchar2fs.c _uint2fs.c _ulong2fs.c \ + calloc.c malloc.c realloc.c free.c \ + serial.c ser_ir.c printfl.c \ printf_large.c vprintf.c puts.c gets.c \ assert.c _strcat.c time.c printf_fast.c bpx.c \ fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \ @@ -83,14 +85,14 @@ Z80SOURCES = _atof.c _atoi.c \ _modslong.c _modulong.c \ _mullong.c \ _divslong.c _divulong.c \ - malloc.c \ + calloc.c malloc.c realloc.c free.c \ _fs2schar.c _fs2sint.c _fs2slong.c \ _fs2uchar.c _fs2uint.c _fs2ulong.c _fsadd.c \ _fsdiv.c _fseq.c _fsgt.c _fslt.c _fsmul.c \ _fsneq.c _fssub.c \ _uchar2fs.c _uint2fs.c \ _ulong2fs.c \ - _slong2fs.c _sint2fs.c _schar2fs.c + _slong2fs.c _sint2fs.c _schar2fs.c Z80OBJECTS = $(Z80SOURCES:%.c=$(PORTDIR)/%.o) @@ -108,8 +110,10 @@ XA51SOURCES = _atof.c _atoi.c _atol.c _schar2fs.c \ _strchr.c _strcmp.c _strcpy.c \ _strcspn.c _strlen.c _strncat.c _strncmp.c \ _strncpy.c _strpbrk.c _strrchr.c _strspn.c \ - _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \ - _ulong2fs.c malloc.c puts.c gets.c \ + _strstr.c _strtok.c \ + _uchar2fs.c _uint2fs.c _ulong2fs.c \ + calloc.c malloc.c realloc.c free.c \ + puts.c gets.c \ printf_large.c puts.c gets.c \ assert.c _strcat.c time.c \ fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \ @@ -134,8 +138,9 @@ HC08SOURCES = _atof.c _atoi.c _atol.c _schar2fs.c \ _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \ _strcspn.c _strlen.c _strncat.c _strncmp.c \ _strncpy.c _strpbrk.c _strrchr.c _strspn.c \ - _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \ - _ulong2fs.c malloc.c \ + _strstr.c _strtok.c \ + _uchar2fs.c _uint2fs.c _ulong2fs.c \ + calloc.c malloc.c realloc.c free.c \ assert.c _strcat.c time.c \ fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \ cosf.c logf.c log10f.c sqrtf.c tancotf.c tanf.c cotf.c \ @@ -167,11 +172,11 @@ model-ds390: if [ "`grep ds390 ../../ports.build`" = ds390 ]; then \ $(MAKE) MODELFLAGS="-mds390" PORT=ds390 objects; \ fi - + model-ds400: if [ "`grep ds400 ../../ports.build`" = ds400 ]; then \ $(MAKE) MODELFLAGS="-mds400" PORT=ds400 objects; \ - fi + fi model-xa51: if [ "`grep xa51 ../../ports.build`" = xa51 ]; then \ @@ -197,7 +202,7 @@ objects-z80: build-dir $(Z80OBJECTS) port-specific-objects clean_intermediate model-hc08: if [ "`grep hc08 ../../ports.build`" = hc08 ]; then \ $(MAKE) MODELFLAGS="-mhc08" PORT=hc08 objects-hc08; \ - fi + fi objects-hc08: build-dir $(HC08OBJECTS) port-specific-objects clean_intermediate cd $(PORTDIR); ls *$(OEXT) > $(PORT).lib @@ -240,8 +245,8 @@ clean_intermediate-pic16: # Compiling and installing everything and runing test # --------------------------------------------------- install: all installdirs - cp -r $(BUILDDIR)/* $(sdcc_libdir) - cp -r ds390 ds400 gbz80 z80 hc08 *.c $(sdcc_libdir)/src + cp -r -u $(BUILDDIR)/* $(sdcc_libdir) + cp -r -u ds390 ds400 gbz80 z80 hc08 *.c $(sdcc_libdir)/src rm -r `find $(sdcc_libdir)/src -name '*.rel' -or -name '*.dump*' -or -name '*.sym' -or -name '*.o' -or -name '*.lst' -or -name '*.asm' -or -name 'CVS'` # Deleting all the installed files @@ -268,8 +273,8 @@ installdirs: mkdir -p $(sdcc_libdir)/$$model; \ done [ -d $(sdcc_libdir)/ds390 ] || mkdir -p $(sdcc_libdir)/ds390 - [ -d $(sdcc_libdir)/ds400 ] || mkdir -p $(sdcc_libdir)/ds400 - [ -d $(sdcc_libdir)/hc08 ] || mkdir -p $(sdcc_libdir)/hc08 + [ -d $(sdcc_libdir)/ds400 ] || mkdir -p $(sdcc_libdir)/ds400 + [ -d $(sdcc_libdir)/hc08 ] || mkdir -p $(sdcc_libdir)/hc08 [ -f $(sdcc_libdir)/pic16 ] || mkdir -p $(sdcc_libdir)/pic16 mkdir -p $(sdcc_libdir)/src diff --git a/device/lib/calloc.c b/device/lib/calloc.c new file mode 100644 index 00000000..6abb4242 --- /dev/null +++ b/device/lib/calloc.c @@ -0,0 +1,46 @@ +#include +#include +#include + +//-------------------------------------------------------------------- +//Written by Maarten Brock, 2004 +//-------------------------------------------------------------------- +//calloc function implementation for embedded system +//Non-ANSI keywords are C51 specific. +// xdata - variable in external memory (just RAM) +//-------------------------------------------------------------------- + +#if _SDCC_MALLOC_TYPE_MLH + +#define xdata + +typedef struct _MEMHEADER MEMHEADER; + +struct _MEMHEADER +{ + MEMHEADER * next; + MEMHEADER * prev; + unsigned int len; + unsigned char mem; +}; + +#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char)) + +#else + +#define HEADER_SIZE sizeof(MEMHEADER) + +#endif + +void xdata * calloc (size_t nmemb, size_t size) +{ + register void xdata * ptr; + + ptr = malloc(nmemb * size); + if (ptr) + { + memset(ptr, 0, nmemb * size); + } + return ptr; +} +//END OF MODULE diff --git a/device/lib/free.c b/device/lib/free.c new file mode 100644 index 00000000..ff1c16c4 --- /dev/null +++ b/device/lib/free.c @@ -0,0 +1,122 @@ +#include +#include + +#if _SDCC_MALLOC_TYPE_MLH + +typedef struct _MEMHEADER MEMHEADER; + +struct _MEMHEADER +{ + MEMHEADER * next; + MEMHEADER * prev; + unsigned int len; + unsigned char mem; +}; + +#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char)) + +/* These variables are defined through the crt0 functions. */ +/* Base of this variable is the first byte of the heap. */ +extern MEMHEADER _sdcc_heap_start; +/* Address of this variable is the last byte of the heap. */ +extern char _sdcc_heap_end; + +MEMHEADER * _sdcc_prev_memheader; +// apart from finding the header +// this function also finds it's predecessor +MEMHEADER * +_sdcc_find_memheader(void * p) +{ + register MEMHEADER * pthis; + if (!p) + return NULL; + pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header + _sdcc_prev_memheader = pthis->prev; + + return (pthis); +} + +void +free (void *p) +{ + MEMHEADER *prev_header, *pthis; + + if ( p ) //For allocated pointers only! + { + pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header + if ( pthis->prev ) // For the regular header + { + prev_header = pthis->prev; + prev_header->next = pthis->next; + if (pthis->next) + { + pthis->next->prev = prev_header; + } + } + else + { + pthis->len = 0; //For the first header + } + } +} + +#else + + //-------------------------------------------------------------------- + //Written by Dmitry S. Obukhov, 1997 + //dso@usa.net + //-------------------------------------------------------------------- + //Modified for SDCC by Sandeep Dutta, 1999 + //sandeep.dutta@usa.net + //-------------------------------------------------------------------- + //malloc and free functions implementation for embedded system + //Non-ANSI keywords are C51 specific. + // xdata - variable in external memory (just RAM) + //-------------------------------------------------------------------- + + #define HEADER_SIZE sizeof(MEMHEADER) + + //Static here means: can be accessed from this module only + extern MEMHEADER xdata * _sdcc_first_memheader; + + MEMHEADER xdata * _sdcc_prev_memheader; + // apart from finding the header + // this function also finds it's predecessor + MEMHEADER xdata * _sdcc_find_memheader(void xdata * p) + { + register MEMHEADER xdata * pthis; + register MEMHEADER xdata * cur_header; + + if (!p) + return NULL; + pthis = (MEMHEADER xdata *) p; + pthis -= 1; //to start of header + cur_header = _sdcc_first_memheader; + _sdcc_prev_memheader = NULL; + while (cur_header && pthis != cur_header) + { + _sdcc_prev_memheader = cur_header; + cur_header = cur_header->next; + } + return (cur_header); + } + + void free (void * p) + { + register MEMHEADER xdata * pthis; + + pthis = _sdcc_find_memheader(p); + if (pthis) //For allocated pointers only! + { + if (!_sdcc_prev_memheader) + { + pthis->len = 0; + } + else + { + _sdcc_prev_memheader->next = pthis->next; + } + } + } + //END OF MODULE +#endif diff --git a/device/lib/libsdcc.lib b/device/lib/libsdcc.lib index 867f96e6..77ef0bdf 100644 --- a/device/lib/libsdcc.lib +++ b/device/lib/libsdcc.lib @@ -35,7 +35,10 @@ _bp _spx _atoi _atol +calloc malloc +realloc +free serial _autobaud _startup diff --git a/device/lib/malloc.c b/device/lib/malloc.c index 00439285..cf6f905c 100644 --- a/device/lib/malloc.c +++ b/device/lib/malloc.c @@ -7,15 +7,15 @@ typedef struct _MEMHEADER MEMHEADER; struct _MEMHEADER { - MEMHEADER * next; - MEMHEADER * prev; - unsigned int len; - unsigned char mem; + MEMHEADER * next; + MEMHEADER * prev; + unsigned int len; + unsigned char mem; }; #define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char)) -/* These veriables are defined through the crt0 functions. */ +/* These variables are defined through the crt0 functions. */ /* Base of this variable is the first byte of the heap. */ extern MEMHEADER _sdcc_heap_start; /* Address of this variable is the last byte of the heap. */ @@ -58,14 +58,14 @@ malloc (unsigned int size) if ((((unsigned int)current_header->next) - ((unsigned int)current_header) - - current_header->len) >= size) + current_header->len) >= size) { break; //if spare is more than need } - current_header = current_header->next; //else try next - if (!current_header->next) + current_header = current_header->next; //else try next + if (!current_header->next) { - return NULL; //if end_of_list reached + return NULL; //if end_of_list reached } } @@ -73,7 +73,7 @@ malloc (unsigned int size) { //This code works only for first_header in the list and only current_header->len = size; //for first allocation return ¤t_header->mem; - } + } else { //else create new header at the begin of spare @@ -90,30 +90,6 @@ malloc (unsigned int size) } } -void -free (void *p) -{ - MEMHEADER *prev_header, *pthis; - - if ( p ) //For allocated pointers only! - { - pthis = (MEMHEADER * )((char *) p - HEADER_SIZE); //to start of header - if ( pthis->prev ) // For the regular header - { - prev_header = pthis->prev; - prev_header->next = pthis->next; - if (pthis->next) - { - pthis->next->prev = prev_header; - } - } - else - { - pthis->len = 0; //For the first header - } - } -} - #else //-------------------------------------------------------------------- @@ -128,26 +104,16 @@ free (void *p) // xdata - variable in external memory (just RAM) //-------------------------------------------------------------------- - #define MEMHEADER struct MAH// Memory Allocation Header - - MEMHEADER - { - MEMHEADER xdata * next; - MEMHEADER xdata * prev; - unsigned int len; - unsigned char mem; - }; + #define HEADER_SIZE sizeof(MEMHEADER) - #define HEADER_SIZE (sizeof(MEMHEADER)-1) + MEMHEADER xdata * _sdcc_first_memheader; - //Static here means: can be accessed from this module only - static MEMHEADER xdata * FIRST_MEMORY_HEADER_PTR; - void init_dynamic_memory(MEMHEADER xdata * array, unsigned int size) + void init_dynamic_memory(void xdata * heap, unsigned int size) { //This function MUST be called after the RESET. - //Parameters: array - pointer to memory allocated by the linker - // size - size of this memory pool + //Parameters: heap - pointer to memory allocated by the linker + // size - size of this memory pool //Example: // #define DYNAMIC_MEMORY_SIZE 0x2000 // ..... @@ -163,28 +129,28 @@ free (void *p) // current_buffer = malloc(0x100); // // + MEMHEADER xdata * array = (MEMHEADER xdata *)heap; - if ( !array ) /*Reserved memory starts on 0x0000 but it's NULL...*/ + if ( !array ) //Reserved memory starts at 0x0000 but that's NULL... { //So, we lost one byte! array = (MEMHEADER xdata * )((char xdata * ) array + 1) ; - size --; + size--; } - FIRST_MEMORY_HEADER_PTR = array; + _sdcc_first_memheader = array; //Reserve a mem for last header - array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - HEADER_SIZE); - array->next->next = (void xdata * ) NULL; //And mark it as last - array->prev = (void xdata * ) NULL; //and mark first as first + array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - sizeof(MEMHEADER xdata *)); + array->next->next = (MEMHEADER xdata * ) NULL; //And mark it as last array->len = 0; //Empty and ready. } - void xdata * malloc (unsigned int size) + void xdata * malloc (unsigned int size) { register MEMHEADER xdata * current_header; register MEMHEADER xdata * new_header; 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 - current_header = FIRST_MEMORY_HEADER_PTR; + current_header = _sdcc_first_memheader; while (1) { @@ -198,38 +164,20 @@ free (void *p) if ((((unsigned int)current_header->next) - ((unsigned int)current_header) - current_header->len) >= size) break; //if spare is more than need - current_header = current_header->next; //else try next + current_header = current_header->next; //else try next if (!current_header->next) return (void xdata *) NULL; //if end_of_list reached } if (!current_header->len) { //This code works only for first_header in the list and only current_header->len = size; //for first allocation - return ((xdata *)&(current_header->mem)); + return current_header->mem; } //else create new header at the begin of spare new_header = (MEMHEADER xdata * )((char xdata *)current_header + current_header->len); new_header->next = current_header->next; //and plug it into the chain - new_header->prev = current_header; current_header->next = new_header; - if (new_header->next) new_header->next->prev = new_header; new_header->len = size; //mark as used - return ((xdata *)&(new_header->mem)); + return new_header->mem; } - void free (void xdata * p) - { - register MEMHEADER xdata * prev_header; - if ( p ) //For allocated pointers only! - { - p = (MEMHEADER xdata * )((char xdata *) p - HEADER_SIZE); //to start of header - if ( ((MEMHEADER xdata * ) p)->prev ) // For the regular header - { - prev_header = ((MEMHEADER xdata * ) p)->prev; - prev_header->next = ((MEMHEADER xdata * ) p)->next; - if (((MEMHEADER xdata * ) p)->next) - ((MEMHEADER xdata * ) p)->next->prev = prev_header; - } - else ((MEMHEADER xdata * ) p)->len = 0; //For the first header - } - } //END OF MODULE #endif diff --git a/device/lib/realloc.c b/device/lib/realloc.c new file mode 100644 index 00000000..54fde7f9 --- /dev/null +++ b/device/lib/realloc.c @@ -0,0 +1,83 @@ +#include +#include +#include + +//-------------------------------------------------------------------- +//Written by Maarten Brock, 2004 +//-------------------------------------------------------------------- +//realloc function implementation for embedded system +//Non-ANSI keywords are C51 specific. +// xdata - variable in external memory (just RAM) +//-------------------------------------------------------------------- + +#if _SDCC_MALLOC_TYPE_MLH + +#define xdata + +typedef struct _MEMHEADER MEMHEADER; + +struct _MEMHEADER +{ + MEMHEADER * next; + MEMHEADER * prev; + unsigned int len; + unsigned char mem; +}; + +#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char)) + +#else + +#define HEADER_SIZE sizeof(MEMHEADER) + +#endif + +extern MEMHEADER xdata * _sdcc_prev_memheader; + +// apart from finding the header +// this function also finds it's predecessor +extern MEMHEADER xdata * _sdcc_find_memheader(void xdata * p); + +void xdata * realloc (void * p, size_t size) +{ + register MEMHEADER xdata * pthis; + register MEMHEADER xdata * pnew; + + pthis = _sdcc_find_memheader(p); + if (pthis) + { + 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 + + if ((((unsigned int)pthis->next) - ((unsigned int)pthis)) >= size) + {//if spare is more than need + pthis->len = size; + return p; + } + + 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; + } + + pnew = malloc(size - HEADER_SIZE); + if (pnew) + { + memcpy(pnew, pthis->mem, pthis->len - HEADER_SIZE); + free(p); + } + return pnew; + } + else + { + return malloc(size); + } +} +//END OF MODULE