From 73e6ccc14e902240c9405b2c7f5fa39581a1f75d Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Fri, 24 Dec 2004 11:46:12 +0000 Subject: [PATCH] - 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 --- library/changes | 6 +++ library/smakefile | 3 +- library/stdlib_alloca.c | 61 +++++++++++++++++--------- library/stdlib_data.c | 42 ++---------------- library/stdlib_free.c | 74 ++++++++++++++++++++++++++++++-- library/stdlib_headers.h | 6 +-- library/stdlib_init_exit.c | 76 ++------------------------------- library/stdlib_malloc.c | 35 +++++++++++++-- library/stdlib_protos.h | 6 ++- library/stdlib_rand.c | 7 ++- library/stdlib_stackcheck.c | 14 +++++- library/stdlib_stackextension.c | 7 ++- 12 files changed, 189 insertions(+), 148 deletions(-) diff --git a/library/changes b/library/changes index 6d83e1b..a6b5acd 100644 --- a/library/changes +++ b/library/changes @@ -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) diff --git a/library/smakefile b/library/smakefile index 2176355..00b874c 100644 --- a/library/smakefile +++ b/library/smakefile @@ -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 \ diff --git a/library/stdlib_alloca.c b/library/stdlib_alloca.c index 9228c3b..fa04997 100644 --- a/library/stdlib_alloca.c +++ b/library/stdlib_alloca.c @@ -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; diff --git a/library/stdlib_data.c b/library/stdlib_data.c index 99cea30..edaf081 100644 --- a/library/stdlib_data.c +++ b/library/stdlib_data.c @@ -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; /****************************************************************************/ diff --git a/library/stdlib_free.c b/library/stdlib_free.c index 6791646..ce12ffd 100644 --- a/library/stdlib_free.c +++ b/library/stdlib_free.c @@ -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(); +} diff --git a/library/stdlib_headers.h b/library/stdlib_headers.h index 6488e28..49cb0e3 100644 --- a/library/stdlib_headers.h +++ b/library/stdlib_headers.h @@ -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; diff --git a/library/stdlib_init_exit.c b/library/stdlib_init_exit.c index 5b32087..bb2c76b 100644 --- a/library/stdlib_init_exit.c +++ b/library/stdlib_init_exit.c @@ -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); diff --git a/library/stdlib_malloc.c b/library/stdlib_malloc.c index 5162fd1..954fb2b 100644 --- a/library/stdlib_malloc.c +++ b/library/stdlib_malloc.c @@ -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(); +} diff --git a/library/stdlib_protos.h b/library/stdlib_protos.h index 865c014..f68a482 100644 --- a/library/stdlib_protos.h +++ b/library/stdlib_protos.h @@ -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); diff --git a/library/stdlib_rand.c b/library/stdlib_rand.c index 07f102a..7e82741 100644 --- a/library/stdlib_rand.c +++ b/library/stdlib_rand.c @@ -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) { diff --git a/library/stdlib_stackcheck.c b/library/stdlib_stackcheck.c index a5020aa..65bed64 100644 --- a/library/stdlib_stackcheck.c +++ b/library/stdlib_stackcheck.c @@ -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) { diff --git a/library/stdlib_stackextension.c b/library/stdlib_stackextension.c index d41d2fa..08a80d1 100644 --- a/library/stdlib_stackextension.c +++ b/library/stdlib_stackextension.c @@ -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) {