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

- Moved the memory initialization and cleanup functions into the

malloc/free code itself and updated the alloca code to do its
  own data management.

- Finally optimized the alloca() memory cleanup code.


git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14784 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2004-12-24 11:46:12 +00:00
parent 3c9f119046
commit 73e6ccc14e
12 changed files with 189 additions and 148 deletions

View File

@ -5,6 +5,12 @@
- The common error reporting function __show_error() could throw Enforcer
hits if the program was not launched from Shell. Fixed.
- Moved the memory initialization and cleanup functions into the
malloc/free code itself and updated the alloca code to do its
own data management.
- Finally optimized the alloca() memory cleanup code.
c.lib 1.184 (28.11.2004)

View File

@ -1,5 +1,5 @@
#
# $Id: smakefile,v 1.12 2004-11-18 09:40:37 obarthel Exp $
# $Id: smakefile,v 1.13 2004-12-24 11:46:12 obarthel Exp $
#
# :ts=8
#
@ -357,6 +357,7 @@ STDIO_OBJ = \
STDLIB_OBJ = \
stdlib_abort.o \
stdlib_abs.o \
stdlib_alloca.o \
stdlib_assertion_failure.o \
stdlib_atexit.o \
stdlib_atof.o \

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_alloca.c,v 1.1.1.1 2004-07-26 16:31:50 obarthel Exp $
* $Id: stdlib_alloca.c,v 1.2 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -52,34 +52,55 @@ extern void * alloca(size_t size);
struct MemoryContextNode
{
struct MinNode mcn_MinNode;
ULONG mcn_StackPointer;
char * mcn_Memory;
void * mcn_StackPointer;
void * mcn_Memory;
};
/****************************************************************************/
extern unsigned long __get_sp(void);
static struct MinList alloca_memory_list;
/****************************************************************************/
CLIB_DESTRUCTOR(__alloca_exit)
{
ENTER();
/* Clean this up, too, just to be safe. */
NewList((struct List *)&alloca_memory_list);
LEAVE();
}
/****************************************************************************/
void
__alloca_cleanup(const char * file,int line)
{
ULONG stack_pointer = __get_sp();
struct MemoryContextNode * mcn_next;
struct MemoryContextNode * mcn;
/* Initialize this if it hasn't been taken care of yet. */
if(alloca_memory_list.mlh_Head == NULL)
NewList((struct List *)&alloca_memory_list);
/* ZZZ this could be done in a much smarter fashion by paying attention
* to the fact that the 'mcn_StackPointer' members are sorted...
*/
for(mcn = (struct MemoryContextNode *)__alloca_memory_list.mlh_Head ;
mcn->mcn_MinNode.mln_Succ != NULL ;
mcn = mcn_next)
/* Is this worth cleaning up? */
if(NOT IsListEmpty((struct List *)&alloca_memory_list))
{
mcn_next = (struct MemoryContextNode *)mcn->mcn_MinNode.mln_Succ;
void * stack_pointer = __get_sp();
struct MemoryContextNode * mcn_prev;
struct MemoryContextNode * mcn;
if(mcn->mcn_StackPointer < stack_pointer)
/* The assumption is that the stack grows downwards. If this function is
called, we must get rid off all the allocations associated with stack
pointers whose addresses are less than the current stack pointer.
Which so happen to be stored near the end of the list. The further
we move up from the end to the top of the list, the closer we get
to the allocations made in the context of a stack frame near to
where were currently are. */
for(mcn = (struct MemoryContextNode *)alloca_memory_list.mlh_TailPred ;
mcn->mcn_MinNode.mln_Pred != NULL && mcn->mcn_StackPointer < stack_pointer ;
mcn = mcn_prev)
{
mcn_prev = (struct MemoryContextNode *)mcn->mcn_MinNode.mln_Pred;
Remove((struct Node *)mcn);
__force_free(mcn->mcn_Memory,file,line);
@ -93,7 +114,7 @@ __alloca_cleanup(const char * file,int line)
void *
__alloca(size_t size,const char * file,int line)
{
ULONG stack_pointer = __get_sp();
void * stack_pointer = __get_sp();
struct MemoryContextNode * mcn;
void * result = NULL;
@ -124,9 +145,7 @@ __alloca(size_t size,const char * file,int line)
goto out;
}
/* Allocate memory which cannot be run through realloc()
* or free().
*/
/* Allocate memory which cannot be run through realloc() or free(). */
mcn->mcn_Memory = __allocate_memory(size,TRUE,file,line);
if(mcn->mcn_Memory == NULL)
{
@ -138,7 +157,9 @@ __alloca(size_t size,const char * file,int line)
mcn->mcn_StackPointer = stack_pointer;
AddTail((struct List *)&__alloca_memory_list,(struct Node *)mcn);
assert( alloca_memory_list.mlh_Head != NULL );
AddTail((struct List *)&alloca_memory_list,(struct Node *)mcn);
result = mcn->mcn_Memory;

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_data.c,v 1.3 2004-11-14 11:06:27 obarthel Exp $
* $Id: stdlib_data.c,v 1.4 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -43,28 +43,6 @@
/****************************************************************************/
/* NOTE: for Knuth's algorithm below the seed must not be zero. */
unsigned __random_seed = 1;
/****************************************************************************/
#if defined(__USE_MEM_TREES) && defined(__MEM_DEBUG)
struct MemoryTree __memory_tree;
#endif /* __USE_MEM_TREES && __MEM_DEBUG */
/****************************************************************************/
APTR __memory_pool;
struct MinList __memory_list;
/****************************************************************************/
struct MinList __alloca_memory_list;
/****************************************************************************/
struct WBStartup * __WBenchMsg;
/****************************************************************************/
@ -74,21 +52,9 @@ BOOL __free_program_name;
/****************************************************************************/
BOOL __stack_overflow;
UBYTE * __stk_limit;
/*UBYTE ** __stackborders;*/
/*UBYTE * __stk_initial;*/
ULONG __stk_maxsize;
ULONG __stk_size;
ULONG __stk_extensions;
/****************************************************************************/
#if defined(__SASC)
UBYTE * __base;
#endif /* __SASC */
BOOL __stack_overflow;
ULONG __stk_maxsize;
ULONG __stk_extensions;
/****************************************************************************/

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_free.c,v 1.1.1.1 2004-07-26 16:31:55 obarthel Exp $
* $Id: stdlib_free.c,v 1.2 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -441,8 +441,7 @@ free_memory(void * ptr,BOOL force,const char * file,int line)
assert(ptr != NULL);
/* Try to get rid of now unused memory. */
/*if(NOT IsListEmpty((struct List *)&__alloca_memory_list))
__alloca_cleanup(file,line);*/
/*__alloca_cleanup(file,line);*/
#ifdef __MEM_DEBUG
{
@ -510,3 +509,72 @@ free(void * ptr)
{
__free(ptr,NULL,0);
}
/****************************************************************************/
void
__memory_exit(void)
{
ENTER();
#ifdef __MEM_DEBUG
{
kprintf("[%s] %ld bytes still allocated upon exit, maximum of %ld bytes allocated at a time.\n",
__program_name,__current_memory_allocated,__maximum_memory_allocated);
kprintf("[%s] %ld chunks of memory still allocated upon exit, maximum of %ld chunks allocated at a time.\n",
__program_name,__current_num_memory_chunks_allocated,__maximum_num_memory_chunks_allocated);
__check_memory_allocations(__FILE__,__LINE__);
}
#endif /* __MEM_DEBUG */
#if defined(__MEM_DEBUG)
{
__never_free = FALSE;
if(__memory_list.mlh_Head != NULL)
{
while(NOT IsListEmpty((struct List *)&__memory_list))
{
((struct MemoryNode *)__memory_list.mlh_Head)->mn_AlreadyFree = FALSE;
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__);
}
}
}
#endif /* __MEM_DEBUG */
#if defined(__USE_MEM_TREES) && defined(__MEM_DEBUG)
{
__initialize_red_black_tree(&__memory_tree);
}
#endif /* __USE_MEM_TREES && __MEM_DEBUG */
if(__memory_pool != NULL)
{
NewList((struct List *)&__memory_list);
DeletePool(__memory_pool);
__memory_pool = NULL;
}
else
{
if(__memory_list.mlh_Head != NULL)
{
#ifdef __MEM_DEBUG
{
while(NOT IsListEmpty((struct List *)&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__);
}
#else
{
while(NOT IsListEmpty((struct List *)&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,NULL,0);
}
#endif /* __MEM_DEBUG */
}
}
LEAVE();
}

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_headers.h,v 1.3 2004-12-19 16:42:51 obarthel Exp $
* $Id: stdlib_headers.h,v 1.4 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -159,10 +159,6 @@ extern APTR NOCOMMON __memory_pool;
/****************************************************************************/
extern struct MinList NOCOMMON __alloca_memory_list;
/****************************************************************************/
extern unsigned long NOCOMMON __maximum_memory_allocated;
extern unsigned long NOCOMMON __current_memory_allocated;
extern unsigned long NOCOMMON __maximum_num_memory_chunks_allocated;

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_init_exit.c,v 1.2 2004-12-19 16:42:51 obarthel Exp $
* $Id: stdlib_init_exit.c,v 1.3 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -48,67 +48,7 @@ __stdlib_exit(void)
{
ENTER();
#ifdef __MEM_DEBUG
{
kprintf("[%s] %ld bytes still allocated upon exit, maximum of %ld bytes allocated at a time.\n",
__program_name,__current_memory_allocated,__maximum_memory_allocated);
kprintf("[%s] %ld chunks of memory still allocated upon exit, maximum of %ld chunks allocated at a time.\n",
__program_name,__current_num_memory_chunks_allocated,__maximum_num_memory_chunks_allocated);
__check_memory_allocations(__FILE__,__LINE__);
}
#endif /* __MEM_DEBUG */
/* Clean this up, too, just to be safe. */
NewList((struct List *)&__alloca_memory_list);
#if defined(__MEM_DEBUG)
{
__never_free = FALSE;
if(__memory_list.mlh_Head != NULL)
{
while(NOT IsListEmpty((struct List *)&__memory_list))
{
((struct MemoryNode *)__memory_list.mlh_Head)->mn_AlreadyFree = FALSE;
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__);
}
}
}
#endif /* __MEM_DEBUG */
#if defined(__USE_MEM_TREES) && defined(__MEM_DEBUG)
{
__initialize_red_black_tree(&__memory_tree);
}
#endif /* __USE_MEM_TREES && __MEM_DEBUG */
if(__memory_pool != NULL)
{
NewList((struct List *)&__memory_list);
DeletePool(__memory_pool);
__memory_pool = NULL;
}
else
{
if(__memory_list.mlh_Head != NULL)
{
#ifdef __MEM_DEBUG
{
while(NOT IsListEmpty((struct List *)&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__);
}
#else
{
while(NOT IsListEmpty((struct List *)&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,NULL,0);
}
#endif /* __MEM_DEBUG */
}
}
__memory_exit();
if(__free_program_name && __program_name != NULL)
{
@ -126,17 +66,7 @@ __stdlib_init(void)
{
ENTER();
#if defined(__USE_MEM_TREES) && defined(__MEM_DEBUG)
{
__initialize_red_black_tree(&__memory_tree);
}
#endif /* __USE_MEM_TREES && __MEM_DEBUG */
NewList((struct List *)&__memory_list);
NewList((struct List *)&__alloca_memory_list);
if(((struct Library *)SysBase)->lib_Version >= 39)
__memory_pool = CreatePool(MEMF_ANY,(ULONG)__default_pool_size,(ULONG)__default_puddle_size);
__memory_init();
RETURN(OK);
return(OK);

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_malloc.c,v 1.1.1.1 2004-07-26 16:31:59 obarthel Exp $
* $Id: stdlib_malloc.c,v 1.2 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -54,10 +54,19 @@ unsigned long __current_memory_allocated;
unsigned long __maximum_num_memory_chunks_allocated;
unsigned long __current_num_memory_chunks_allocated;
#if defined(__USE_MEM_TREES)
struct MemoryTree __memory_tree;
#endif /* __USE_MEM_TREES */
#endif /* __MEM_DEBUG */
/****************************************************************************/
APTR __memory_pool;
struct MinList __memory_list;
/****************************************************************************/
size_t
__get_allocation_size(size_t size)
{
@ -203,8 +212,7 @@ __malloc(size_t size,const char * file,int line)
void * result = NULL;
/* Try to get rid of now unused memory. */
/*if(NOT IsListEmpty((struct List *)&__alloca_memory_list))
__alloca_cleanup(file,line);*/
/*__alloca_cleanup(file,line);*/
#ifdef __MEM_DEBUG
{
@ -250,3 +258,24 @@ malloc(size_t size)
return(result);
}
/****************************************************************************/
void
__memory_init(void)
{
ENTER();
#if defined(__USE_MEM_TREES) && defined(__MEM_DEBUG)
{
__initialize_red_black_tree(&__memory_tree);
}
#endif /* __USE_MEM_TREES && __MEM_DEBUG */
NewList((struct List *)&__memory_list);
if(((struct Library *)SysBase)->lib_Version >= 39)
__memory_pool = CreatePool(MEMF_ANY,(ULONG)__default_pool_size,(ULONG)__default_puddle_size);
LEAVE();
}

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_protos.h,v 1.2 2004-09-29 14:17:44 obarthel Exp $
* $Id: stdlib_protos.h,v 1.3 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -100,7 +100,7 @@ extern int __swap_stack_and_call(struct StackSwapStruct * stk,APTR function);
/****************************************************************************/
/* stdlib_get_sp.c/stdlib_get_sp.s/stdlib_get_sp.asm */
extern unsigned long __get_sp(void);
extern void * __get_sp(void);
/****************************************************************************/
@ -138,11 +138,13 @@ extern int __startup_init(void);
/****************************************************************************/
/* stdlib_malloc.c */
extern void __memory_init(void);
extern size_t __get_allocation_size(size_t size);
extern void * __allocate_memory(size_t size,BOOL never_free,const char * file,int line);
extern void * __malloc(size_t size,const char * file,int line);
/* stdlib_free.c */
extern void __memory_exit(void);
extern struct MemoryNode * __find_memory_node(void * address);
extern void __force_free(void * ptr,const char * file,int line);
extern void __check_memory_allocations(const char * file,int line);

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_rand.c,v 1.1.1.1 2004-07-26 16:32:02 obarthel Exp $
* $Id: stdlib_rand.c,v 1.2 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -48,6 +48,11 @@
/****************************************************************************/
/* NOTE: for Knuth's algorithm below the seed must not be zero. */
unsigned __random_seed = 1;
/****************************************************************************/
int
rand(void)
{

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_stackcheck.c,v 1.2 2004-09-29 14:17:44 obarthel Exp $
* $Id: stdlib_stackcheck.c,v 1.3 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -103,6 +103,18 @@ overflow: \n\
/****************************************************************************/
UBYTE * __stk_limit;
/****************************************************************************/
#if defined(__SASC)
UBYTE * __base;
#endif /* __SASC */
/****************************************************************************/
int
__stk_init(void)
{

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_stackextension.c,v 1.2 2004-09-29 14:17:44 obarthel Exp $
* $Id: stdlib_stackextension.c,v 1.3 2004-12-24 11:46:12 obarthel Exp $
*
* :ts=4
*
@ -272,6 +272,11 @@ endlp:
/****************************************************************************/
UBYTE * __stk_limit;
ULONG __stk_size;
/****************************************************************************/
int
__stk_init(void)
{