From 0459ea1fc9f8776c512998301037f7ec55070a9f Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Sun, 20 Nov 2005 17:00:22 +0000 Subject: [PATCH] - In libunix.a malloc(), calloc() and realloc() no longer treat a request to allocate 0 bytes as an error, returning NULL. They all return a 1 byte memory chunk initialized to 0 instead. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15064 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 4 +++- library/GNUmakefile.os4 | 4 +++- library/changes | 4 ++++ library/stdlib_alloca.c | 22 ++--------------- library/stdlib_calloc.c | 24 ++++++------------- library/stdlib_malloc.c | 52 ++++++++++++++++++++-------------------- library/stdlib_realloc.c | 36 +++++++++++----------------- 7 files changed, 59 insertions(+), 87 deletions(-) diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index 3c4d07d..f1651e0 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.74 2005-11-19 17:11:22 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.75 2005-11-20 17:00:22 obarthel Exp $ # # :ts=8 # @@ -491,6 +491,8 @@ UNIX_LIB = \ stdlib_mkdtemp.o \ stdlib_mkstemp.o \ stdlib_mktemp.o \ + stdlib_malloc.o \ + stdlib_realloc.o \ stdlib_system.o \ termios_cfgetispeed.o \ termios_cfgetospeed.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 1feb3cf..1c6cdae 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.86 2005-11-19 17:11:22 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.87 2005-11-20 17:00:22 obarthel Exp $ # # :ts=8 # @@ -526,6 +526,8 @@ UNIX_LIB = \ stdlib_mkdtemp.o \ stdlib_mkstemp.o \ stdlib_mktemp.o \ + stdlib_malloc.o \ + stdlib_realloc.o \ stdlib_system.o \ termios_cfgetispeed.o \ termios_cfgetospeed.o \ diff --git a/library/changes b/library/changes index de54bb2..e962ddb 100644 --- a/library/changes +++ b/library/changes @@ -6,6 +6,10 @@ - Replaced the old pow() implementation. However, powf() may need to be changed to set a domain error. +- In libunix.a malloc(), calloc() and realloc() no longer treat a + request to allocate 0 bytes as an error, returning NULL. They all + return a 1 byte memory chunk initialized to 0 instead. + c.lib 1.197 (4.11.2005) diff --git a/library/stdlib_alloca.c b/library/stdlib_alloca.c index ba8698d..73fb9ac 100644 --- a/library/stdlib_alloca.c +++ b/library/stdlib_alloca.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_alloca.c,v 1.6 2005-03-18 12:38:23 obarthel Exp $ + * $Id: stdlib_alloca.c,v 1.7 2005-11-20 17:00:22 obarthel Exp $ * * :ts=4 * @@ -126,25 +126,7 @@ __alloca(size_t size,const char * file,int line) __alloca_cleanup(file,line); - assert( (int)size >= 0 ); - - if(size == 0) - { - #ifdef __MEM_DEBUG - { - kprintf("[%s] ",__program_name); - - if(file != NULL) - kprintf("%s:%ld:",file,line); - - kprintf("alloca(0) called.\n"); - } - #endif /* __MEM_DEBUG */ - - goto out; - } - - mcn = __allocate_memory(sizeof(*mcn),FALSE,file,line); + mcn = __malloc(sizeof(*mcn),file,line); if(mcn == NULL) { SHOWMSG("not enough memory"); diff --git a/library/stdlib_calloc.c b/library/stdlib_calloc.c index 706ba3a..55348e5 100644 --- a/library/stdlib_calloc.c +++ b/library/stdlib_calloc.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_calloc.c,v 1.5 2005-03-18 12:38:23 obarthel Exp $ + * $Id: stdlib_calloc.c,v 1.6 2005-11-20 17:00:22 obarthel Exp $ * * :ts=4 * @@ -51,6 +51,7 @@ __static void * __calloc(size_t num_elements,size_t element_size,const char * file,int line) { void * result = NULL; + size_t total_size; #ifdef __MEM_DEBUG { @@ -58,24 +59,13 @@ __calloc(size_t num_elements,size_t element_size,const char * file,int line) } #endif /* __MEM_DEBUG */ - assert( (int)num_elements >= 0 && (int)element_size >= 0 ); + total_size = num_elements * element_size; - if(num_elements > 0 && element_size > 0) - { - size_t total_size; - - total_size = num_elements * element_size; - - result = __malloc(total_size,file,line); - if(result != NULL) - memset(result,0,total_size); - else - SHOWMSG("memory allocation failure"); - } + result = __malloc(total_size,file,line); + if(result != NULL) + memset(result,0,total_size); else - { - SHOWMSG("zero length allocation"); - } + SHOWMSG("memory allocation failure"); return(result); } diff --git a/library/stdlib_malloc.c b/library/stdlib_malloc.c index eaf7451..67f3c90 100644 --- a/library/stdlib_malloc.c +++ b/library/stdlib_malloc.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_malloc.c,v 1.14 2005-10-27 08:58:41 obarthel Exp $ + * $Id: stdlib_malloc.c,v 1.15 2005-11-20 17:00:22 obarthel Exp $ * * :ts=4 * @@ -99,16 +99,28 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED unused_file,in struct MemoryNode * mn; size_t allocation_size; void * result = NULL; + size_t original_size; - assert( size > 0 ); + #if defined(UNIX_PATH_SEMANTICS) + { + original_size = size; + + /* The libunix.a flavour accepts zero length memory allocations + and quietly turns them into 1 byte allocations. */ + if(size == 0) + size++; + } + #endif /* UNIX_PATH_SEMANTICS */ __memory_lock(); + /* Zero length allocations are by default rejected. */ + if(size == 0) + goto out; + if(__free_memory_threshold > 0 && AvailMem(MEMF_ANY|MEMF_LARGEST) < __free_memory_threshold) { SHOWMSG("not enough free memory available to safely proceed with allocation"); - - __set_errno(ENOMEM); goto out; } @@ -137,8 +149,6 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED unused_file,in if(mn == NULL) { SHOWMSG("not enough memory"); - - __set_errno(ENOMEM); goto out; } @@ -195,6 +205,16 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED unused_file,in } #endif /* __MEM_DEBUG */ + #if defined(UNIX_PATH_SEMANTICS) + { + /* Zero length memory allocations in libunix.a quietly + return one byte of memory each, and that byte is + set to '\0'. */ + if(original_size == 0) + *(char *)result = '\0'; + } + #endif /* UNIX_PATH_SEMANTICS */ + assert( (((ULONG)result) & 3) == 0 ); out: @@ -232,29 +252,9 @@ __malloc(size_t size,const char * file,int line) } #endif /* __MEM_DEBUG */ - if(size == 0) - { - #ifdef __MEM_DEBUG - { - kprintf("[%s] ",__program_name); - - if(file != NULL) - kprintf("%s:%ld:",file,line); - - kprintf("malloc(0) called.\n"); - } - #endif /* __MEM_DEBUG */ - - goto out; - } - - assert( (int)size > 0 ); - /* Allocate memory which can be put through realloc() and free(). */ result = __allocate_memory(size,FALSE,file,line); - out: - return(result); } diff --git a/library/stdlib_realloc.c b/library/stdlib_realloc.c index d89fd04..93e470f 100644 --- a/library/stdlib_realloc.c +++ b/library/stdlib_realloc.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_realloc.c,v 1.6 2005-03-18 12:38:24 obarthel Exp $ + * $Id: stdlib_realloc.c,v 1.7 2005-11-20 17:00:22 obarthel Exp $ * * :ts=4 * @@ -65,18 +65,20 @@ __realloc(void *ptr,size_t size,const char * file,int line) result = __malloc(size,file,line); } +#ifndef UNIX_PATH_SEMANTICS else if (size == 0) { D(("calling free(0x%08lx)",ptr)); __free(ptr,file,line); } +#endif /* UNIX_PATH_SEMANTICS */ else { struct MemoryNode * mn; BOOL reallocate; - assert( ptr != NULL && size > 0 ); + assert( ptr != NULL ); /* Try to find the allocation in the list. */ mn = __find_memory_node(ptr); @@ -84,8 +86,7 @@ __realloc(void *ptr,size_t size,const char * file,int line) #ifdef __MEM_DEBUG { /* If we managed to find the memory allocation, - * reallocate it. - */ + reallocate it. */ if(mn == NULL) { SHOWMSG("allocation not found"); @@ -93,9 +94,7 @@ __realloc(void *ptr,size_t size,const char * file,int line) kprintf("[%s] %s:%ld:Address for realloc(0x%08lx,%ld) not known.\n",__program_name,file,line,ptr,size); /* Apparently, the address did not qualify for - * reallocation. - */ - __set_errno(ENOMEM); + reallocation. */ goto out; } } @@ -108,14 +107,11 @@ __realloc(void *ptr,size_t size,const char * file,int line) if(mn == NULL || mn->mn_NeverFree) { SHOWMSG("cannot free this chunk"); - - __set_errno(ENOMEM); goto out; } - /* Don't do anything unless the size of the allocation has really - * changed. - */ + /* Don't do anything unless the size of the allocation + has really changed. */ #if defined(__MEM_DEBUG) { reallocate = (mn->mn_Size != size); @@ -132,19 +128,17 @@ __realloc(void *ptr,size_t size,const char * file,int line) size_t rounded_allocation_size; /* Round the total allocation size to the operating system - * granularity. - */ + granularity. */ rounded_allocation_size = __get_allocation_size(size); assert( rounded_allocation_size >= size ); /* Optimization: If the block size shrinks by less than half the - * original allocation size, do not reallocate the - * block and do not copy over the contents of the old - * allocation. We also take into account that the - * actual size of the allocation is affected by a - * certain operating system imposed granularity. - */ + original allocation size, do not reallocate the + block and do not copy over the contents of the old + allocation. We also take into account that the + actual size of the allocation is affected by a + certain operating system imposed granularity. */ reallocate = (rounded_allocation_size < mn->mn_Size && rounded_allocation_size <= mn->mn_Size / 2); } } @@ -162,8 +156,6 @@ __realloc(void *ptr,size_t size,const char * file,int line) if(new_ptr == NULL) { SHOWMSG("could not reallocate memory"); - - __set_errno(ENOMEM); goto out; }