1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- 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
This commit is contained in:
Olaf Barthel
2005-11-20 17:00:22 +00:00
parent fe29857567
commit 0459ea1fc9
7 changed files with 59 additions and 87 deletions

View File

@ -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 # :ts=8
# #
@ -491,6 +491,8 @@ UNIX_LIB = \
stdlib_mkdtemp.o \ stdlib_mkdtemp.o \
stdlib_mkstemp.o \ stdlib_mkstemp.o \
stdlib_mktemp.o \ stdlib_mktemp.o \
stdlib_malloc.o \
stdlib_realloc.o \
stdlib_system.o \ stdlib_system.o \
termios_cfgetispeed.o \ termios_cfgetispeed.o \
termios_cfgetospeed.o \ termios_cfgetospeed.o \

View File

@ -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 # :ts=8
# #
@ -526,6 +526,8 @@ UNIX_LIB = \
stdlib_mkdtemp.o \ stdlib_mkdtemp.o \
stdlib_mkstemp.o \ stdlib_mkstemp.o \
stdlib_mktemp.o \ stdlib_mktemp.o \
stdlib_malloc.o \
stdlib_realloc.o \
stdlib_system.o \ stdlib_system.o \
termios_cfgetispeed.o \ termios_cfgetispeed.o \
termios_cfgetospeed.o \ termios_cfgetospeed.o \

View File

@ -6,6 +6,10 @@
- Replaced the old pow() implementation. However, powf() may need to - Replaced the old pow() implementation. However, powf() may need to
be changed to set a domain error. 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) c.lib 1.197 (4.11.2005)

View File

@ -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 * :ts=4
* *
@ -126,25 +126,7 @@ __alloca(size_t size,const char * file,int line)
__alloca_cleanup(file,line); __alloca_cleanup(file,line);
assert( (int)size >= 0 ); mcn = __malloc(sizeof(*mcn),file,line);
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);
if(mcn == NULL) if(mcn == NULL)
{ {
SHOWMSG("not enough memory"); SHOWMSG("not enough memory");

View File

@ -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 * :ts=4
* *
@ -51,6 +51,7 @@ __static void *
__calloc(size_t num_elements,size_t element_size,const char * file,int line) __calloc(size_t num_elements,size_t element_size,const char * file,int line)
{ {
void * result = NULL; void * result = NULL;
size_t total_size;
#ifdef __MEM_DEBUG #ifdef __MEM_DEBUG
{ {
@ -58,24 +59,13 @@ __calloc(size_t num_elements,size_t element_size,const char * file,int line)
} }
#endif /* __MEM_DEBUG */ #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) result = __malloc(total_size,file,line);
{ if(result != NULL)
size_t total_size; memset(result,0,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");
}
else else
{ SHOWMSG("memory allocation failure");
SHOWMSG("zero length allocation");
}
return(result); return(result);
} }

View File

@ -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 * :ts=4
* *
@ -99,16 +99,28 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED unused_file,in
struct MemoryNode * mn; struct MemoryNode * mn;
size_t allocation_size; size_t allocation_size;
void * result = NULL; 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(); __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) if(__free_memory_threshold > 0 && AvailMem(MEMF_ANY|MEMF_LARGEST) < __free_memory_threshold)
{ {
SHOWMSG("not enough free memory available to safely proceed with allocation"); SHOWMSG("not enough free memory available to safely proceed with allocation");
__set_errno(ENOMEM);
goto out; goto out;
} }
@ -137,8 +149,6 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED unused_file,in
if(mn == NULL) if(mn == NULL)
{ {
SHOWMSG("not enough memory"); SHOWMSG("not enough memory");
__set_errno(ENOMEM);
goto out; goto out;
} }
@ -195,6 +205,16 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED unused_file,in
} }
#endif /* __MEM_DEBUG */ #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 ); assert( (((ULONG)result) & 3) == 0 );
out: out:
@ -232,29 +252,9 @@ __malloc(size_t size,const char * file,int line)
} }
#endif /* __MEM_DEBUG */ #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(). */ /* Allocate memory which can be put through realloc() and free(). */
result = __allocate_memory(size,FALSE,file,line); result = __allocate_memory(size,FALSE,file,line);
out:
return(result); return(result);
} }

View File

@ -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 * :ts=4
* *
@ -65,18 +65,20 @@ __realloc(void *ptr,size_t size,const char * file,int line)
result = __malloc(size,file,line); result = __malloc(size,file,line);
} }
#ifndef UNIX_PATH_SEMANTICS
else if (size == 0) else if (size == 0)
{ {
D(("calling free(0x%08lx)",ptr)); D(("calling free(0x%08lx)",ptr));
__free(ptr,file,line); __free(ptr,file,line);
} }
#endif /* UNIX_PATH_SEMANTICS */
else else
{ {
struct MemoryNode * mn; struct MemoryNode * mn;
BOOL reallocate; BOOL reallocate;
assert( ptr != NULL && size > 0 ); assert( ptr != NULL );
/* Try to find the allocation in the list. */ /* Try to find the allocation in the list. */
mn = __find_memory_node(ptr); mn = __find_memory_node(ptr);
@ -84,8 +86,7 @@ __realloc(void *ptr,size_t size,const char * file,int line)
#ifdef __MEM_DEBUG #ifdef __MEM_DEBUG
{ {
/* If we managed to find the memory allocation, /* If we managed to find the memory allocation,
* reallocate it. reallocate it. */
*/
if(mn == NULL) if(mn == NULL)
{ {
SHOWMSG("allocation not found"); 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); 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 /* Apparently, the address did not qualify for
* reallocation. reallocation. */
*/
__set_errno(ENOMEM);
goto out; goto out;
} }
} }
@ -108,14 +107,11 @@ __realloc(void *ptr,size_t size,const char * file,int line)
if(mn == NULL || mn->mn_NeverFree) if(mn == NULL || mn->mn_NeverFree)
{ {
SHOWMSG("cannot free this chunk"); SHOWMSG("cannot free this chunk");
__set_errno(ENOMEM);
goto out; goto out;
} }
/* Don't do anything unless the size of the allocation has really /* Don't do anything unless the size of the allocation
* changed. has really changed. */
*/
#if defined(__MEM_DEBUG) #if defined(__MEM_DEBUG)
{ {
reallocate = (mn->mn_Size != size); 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; size_t rounded_allocation_size;
/* Round the total allocation size to the operating system /* Round the total allocation size to the operating system
* granularity. granularity. */
*/
rounded_allocation_size = __get_allocation_size(size); rounded_allocation_size = __get_allocation_size(size);
assert( rounded_allocation_size >= size ); assert( rounded_allocation_size >= size );
/* Optimization: If the block size shrinks by less than half the /* Optimization: If the block size shrinks by less than half the
* original allocation size, do not reallocate the original allocation size, do not reallocate the
* block and do not copy over the contents of the old block and do not copy over the contents of the old
* allocation. We also take into account that the allocation. We also take into account that the
* actual size of the allocation is affected by a actual size of the allocation is affected by a
* certain operating system imposed granularity. certain operating system imposed granularity. */
*/
reallocate = (rounded_allocation_size < mn->mn_Size && rounded_allocation_size <= mn->mn_Size / 2); 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) if(new_ptr == NULL)
{ {
SHOWMSG("could not reallocate memory"); SHOWMSG("could not reallocate memory");
__set_errno(ENOMEM);
goto out; goto out;
} }