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:
@ -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)
|
||||
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user