* [ECOS] New memory allocation debug feature @ 2004-06-17 10:55 Øyvind Harboe 2004-06-17 12:10 ` Andrew Lunn 0 siblings, 1 reply; 7+ messages in thread From: Øyvind Harboe @ 2004-06-17 10:55 UTC (permalink / raw) To: ecos-discuss [-- Attachment #1: Type: text/plain, Size: 54 bytes --] Comments? -- Ãyvind Harboe http://www.zylin.com [-- Attachment #2: memdebug.txt --] [-- Type: text/plain, Size: 9124 bytes --] ? memdebug.txt Index: ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/ChangeLog,v retrieving revision 1.30 diff -w -u -r1.30 ChangeLog --- ChangeLog 15 Mar 2004 15:42:04 -0000 1.30 +++ ChangeLog 17 Jun 2004 10:43:22 -0000 @@ -1,3 +1,8 @@ +2004-06-17 Oyvind Harboe <oyvind.harboe@zylin.com> + + * Added _OutOfMemory() fn which is invoked before return NULL + from failed allocations. Useful breakpoint site. + 2004-02-15 Jonathan Larmour <jifl@eCosCentric.com> * include/kapi.h: Add throw specifications throughout. Index: cdl/memalloc.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/cdl/memalloc.cdl,v retrieving revision 1.12 diff -w -u -r1.12 memalloc.cdl --- cdl/memalloc.cdl 6 Oct 2003 16:41:07 -0000 1.12 +++ cdl/memalloc.cdl 17 Jun 2004 10:43:22 -0000 @@ -239,6 +239,14 @@ forces a NULL pointer to be returned." } + cdl_option CYGSEM_MEMALLOC_INVOKE_OUTOFMEMORY { + display "invoke user supplied _OutOfMemory() function when running out of memory" + default_value 0 + description " + Whenever the system runs out of memory, it invokes this function before either + going to sleep(waiting for memory to become available) or returning failure." + } + cdl_component CYGPKG_MEMALLOC_MALLOC_ALLOCATORS { display "malloc() and supporting allocators" flavor bool Index: include/common.hxx =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/common.hxx,v retrieving revision 1.3 diff -w -u -r1.3 common.hxx --- include/common.hxx 23 May 2002 23:08:43 -0000 1.3 +++ include/common.hxx 17 Jun 2004 10:43:22 -0000 @@ -131,5 +131,15 @@ typedef cyg_uint16 cyg_mempool_status_flag_t; +#if CYGSEM_MEMALLOC_INVOKE_OUTOFMEMORY +// breakpoint site for out of memory conditions +extern "C" void _OutOfMemory(); +#else +// this will compile away to nothing with optimisations turned on. +inline void _OutOfMemory() +{ +} +#endif + #endif /* ifndef CYGONCE_MEMALLOC_COMMON_HXX */ /* EOF common.hxx */ Index: include/memjoin.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/memjoin.inl,v retrieving revision 1.6 diff -w -u -r1.6 memjoin.inl --- include/memjoin.inl 5 Feb 2003 01:10:12 -0000 1.6 +++ include/memjoin.inl 17 Jun 2004 10:43:22 -0000 @@ -178,6 +178,11 @@ } CYG_REPORT_RETVAL( ptr ); + + if (ptr==NULL) + { + _OutOfMemory(); + } return ptr; } // Cyg_Mempool_Joined<T>::try_alloc() @@ -214,6 +219,7 @@ ret = pool->resize_alloc( alloc_ptr, newsize, oldsize ); CYG_REPORT_RETVAL( ret ); + return ret; } // Cyg_Mempool_Joined<T>::resize_alloc() Index: include/mempolt2.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mempolt2.inl,v retrieving revision 1.3 diff -w -u -r1.3 mempolt2.inl --- include/mempolt2.inl 23 May 2002 23:08:43 -0000 1.3 +++ include/mempolt2.inl 17 Jun 2004 10:43:23 -0000 @@ -116,6 +116,8 @@ Mempolt2WaitInfo waitinfo( size ); + _OutOfMemory(); + self->set_wait_info( (CYG_ADDRWORD)&waitinfo ); self->set_sleep_reason( Cyg_Thread::WAIT ); self->sleep(); @@ -187,6 +189,9 @@ // straight to unlock. if( Cyg_Thread::NONE == self->get_wake_reason() ) { + + _OutOfMemory(); + self->set_wait_info( (CYG_ADDRWORD)&waitinfo ); self->sleep(); queue.enqueue( self ); @@ -251,6 +256,12 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + if (ret==NULL) + { + _OutOfMemory(); + } + return ret; } @@ -283,6 +294,12 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + if (ret==NULL) + { + _OutOfMemory(); + } + return ret; } Index: include/mempoolt.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mempoolt.inl,v retrieving revision 1.3 diff -w -u -r1.3 mempoolt.inl --- include/mempoolt.inl 23 May 2002 23:08:43 -0000 1.3 +++ include/mempoolt.inl 17 Jun 2004 10:43:23 -0000 @@ -111,6 +111,9 @@ cyg_uint8 *ret; cyg_bool result = true; while( result && (NULL == (ret = pool.alloc( size ))) ) { + + _OutOfMemory(); + self->set_sleep_reason( Cyg_Thread::WAIT ); self->sleep(); queue.enqueue( self ); @@ -182,6 +185,8 @@ result = false; while( result && (NULL == (ret = pool.alloc( size ))) ) { + _OutOfMemory(); + self->set_sleep_reason( Cyg_Thread::TIMEOUT ); self->sleep(); queue.enqueue( self ); @@ -248,6 +253,11 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( ret ); + + if (ret==NULL) + { + _OutOfMemory(); + } return ret; } Index: include/mfiximpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mfiximpl.inl,v retrieving revision 1.3 diff -w -u -r1.3 mfiximpl.inl --- include/mfiximpl.inl 23 May 2002 23:08:44 -0000 1.3 +++ include/mfiximpl.inl 17 Jun 2004 10:43:23 -0000 @@ -123,7 +123,10 @@ // size parameter is not used CYG_UNUSED_PARAM( cyg_int32, size ); if ( 0 >= freeblocks ) + { + _OutOfMemory(); return NULL; + } cyg_int32 i = firstfree; cyg_uint8 *p = NULL; do { @@ -173,7 +176,10 @@ if (newsize == blocksize) return alloc_ptr; else + { + _OutOfMemory(); return NULL; + } } // resize_alloc() Index: include/mvarimpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mvarimpl.inl,v retrieving revision 1.5 diff -w -u -r1.5 mvarimpl.inl --- include/mvarimpl.inl 23 May 2002 23:08:44 -0000 1.5 +++ include/mvarimpl.inl 17 Jun 2004 10:43:23 -0000 @@ -275,6 +275,10 @@ cyg_uint8 *ptr = memdq2alloc( dq ); CYG_ASSERT( ((CYG_ADDRESS)ptr & (alignment-1)) == 0, "returned memory not aligned" ); + if (ptr==NULL) + { + _OutOfMemory(); + } return ptr; } @@ -358,6 +362,10 @@ ret = alloc_ptr; } + if (ret==NULL) + { + _OutOfMemory(); + } return ret; } // resize_alloc() Index: include/sepmetaimpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.inl,v retrieving revision 1.4 diff -w -u -r1.4 sepmetaimpl.inl --- include/sepmetaimpl.inl 23 May 2002 23:08:44 -0000 1.4 +++ include/sepmetaimpl.inl 17 Jun 2004 10:43:24 -0000 @@ -375,7 +375,10 @@ struct memdq *dq = find_free_dq( size ); if (NULL == dq) + { + _OutOfMemory(); return NULL; + } cyg_int32 dqsize = dq->memnext->mem - dq->mem; @@ -400,7 +403,10 @@ // first get a memdq if ( NULL == freemetahead ) // out of metadata. + { + _OutOfMemory(); return NULL; + } // FIXME: since we don't search all the way for an exact fit // first we may be able to find an exact fit later and therefore @@ -496,7 +502,10 @@ prevmemsize = dq->mem - dq->memprev->mem; } if (nextmemsize + prevmemsize + currsize < newsize) + { + _OutOfMemory(); return NULL; // can't fit it + } // expand forwards if ( nextmemsize != 0 ) { @@ -561,7 +570,10 @@ // if its already allocated we need to create a new free list // entry if (NULL == freemetahead) + { + _OutOfMemory(); return NULL; // can't do it + } struct memdq *fdq = freemetahead; freemetahead = fdq->next; Index: src/dlmalloc.cxx =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/src/dlmalloc.cxx,v retrieving revision 1.8 diff -w -u -r1.8 dlmalloc.cxx --- src/dlmalloc.cxx 6 Oct 2003 18:25:57 -0000 1.8 +++ src/dlmalloc.cxx 17 Jun 2004 10:43:25 -0000 @@ -217,6 +217,8 @@ #include <cyg/memalloc/dlmalloc.hxx> //#include <cyg/infra/diag.h> + + /* Debugging: @@ -1273,6 +1275,7 @@ //diag_printf("chunksize(top)=%ld, nb=%d, remainder=%ld\n", chunksize(top), // nb, remainder_size); MALLOC_UNLOCK; + _OutOfMemory(); return NULL; /* propagate failure */ } @@ -1558,6 +1561,7 @@ // couldn't resize the allocation any direction, so return failure MALLOC_UNLOCK; + _OutOfMemory(); return NULL; } [-- Attachment #3: Type: text/plain, Size: 148 bytes --] -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [ECOS] New memory allocation debug feature 2004-06-17 10:55 [ECOS] New memory allocation debug feature Øyvind Harboe @ 2004-06-17 12:10 ` Andrew Lunn 2004-06-17 13:01 ` Nick Garnett 2004-06-17 14:30 ` Øyvind Harboe 0 siblings, 2 replies; 7+ messages in thread From: Andrew Lunn @ 2004-06-17 12:10 UTC (permalink / raw) To: ?yvind Harboe; +Cc: ecos-discuss On Thu, Jun 17, 2004 at 12:55:11PM +0200, ?yvind Harboe wrote: > Comments? I would prefer the function to use the cyg_ prefix so it does not polute the namespace. You also need to provide an implementation in libtarget.a for when the application does not have such a function. eg all the test programs will not provide this function, so will fail to link when your new option is enabled. So please add a week function which does nothing, or maybe throws an CYG_FAIL(). It would also be nice if you used to same coding style for the patch as for the rest of the file, ie { on the same line as the if etc. Andrew -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [ECOS] New memory allocation debug feature 2004-06-17 12:10 ` Andrew Lunn @ 2004-06-17 13:01 ` Nick Garnett 2004-06-17 14:30 ` Øyvind Harboe 1 sibling, 0 replies; 7+ messages in thread From: Nick Garnett @ 2004-06-17 13:01 UTC (permalink / raw) To: Andrew Lunn; +Cc: ?yvind Harboe, ecos-discuss Andrew Lunn <andrew@lunn.ch> writes: > On Thu, Jun 17, 2004 at 12:55:11PM +0200, ?yvind Harboe wrote: > > Comments? > > I would prefer the function to use the cyg_ prefix so it does not > polute the namespace. To underline this, the naming convention for eCos is to separate words in a name with underscores, not to use capitalization. Names should also contain the subsystem that they belong to and be descriptive of what they do. I think that the function should probably also have some arguments indicating, at least, the size of allocation that failed and the memory pool that has been exhausted. So I would like to see something more like: __externC void cyg_memalloc_alloc_fail( CYG_ADDRESS pool, cyg_uint32 size ); In theory this whole thing should be better integrated into the C++ classes that implement the memory allocators, but having an external function to call is an acceptable first step. > > You also need to provide an implementation in libtarget.a for when the > application does not have such a function. eg all the test programs > will not provide this function, so will fail to link when your new > option is enabled. So please add a week function which does nothing, > or maybe throws an CYG_FAIL(). s/week/weak/ :-) -- Nick Garnett eCos Kernel Architect http://www.ecoscentric.com/ The eCos and RedBoot experts -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [ECOS] New memory allocation debug feature 2004-06-17 12:10 ` Andrew Lunn 2004-06-17 13:01 ` Nick Garnett @ 2004-06-17 14:30 ` Øyvind Harboe 2004-06-18 11:58 ` Andrew Lunn 1 sibling, 1 reply; 7+ messages in thread From: Øyvind Harboe @ 2004-06-17 14:30 UTC (permalink / raw) To: Andrew Lunn; +Cc: ecos-discuss [-- Attachment #1: Type: text/plain, Size: 1048 bytes --] On Thu, 2004-06-17 at 14:10, Andrew Lunn wrote: > On Thu, Jun 17, 2004 at 12:55:11PM +0200, ?yvind Harboe wrote: > > Comments? > > I would prefer the function to use the cyg_ prefix so it does not > polute the namespace. Should be OK now. > You also need to provide an implementation in libtarget.a for when the > application does not have such a function. eg all the test programs > will not provide this function, so will fail to link when your new > option is enabled. So please add a week function which does nothing, > or maybe throws an CYG_FAIL(). Hmmm... Can this be done without adding a new source file? > It would also be nice if you used to same coding style for the patch > as for the rest of the file, ie { on the same line as the if etc. Should be OK now. My dream is that CVS would automatically enforce all such formatting rules transparently, and that text editors would present the source code in the preferred coloring and formatting of the programmer. :-) > > Andrew -- Ãyvind Harboe http://www.zylin.com [-- Attachment #2: memdebug.txt --] [-- Type: text/plain, Size: 8321 bytes --] ? memdebug.txt Index: common/current/include/common.hxx =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/common.hxx,v retrieving revision 1.3 diff -u -w -r1.3 common.hxx --- common/current/include/common.hxx 23 May 2002 23:08:43 -0000 1.3 +++ common/current/include/common.hxx 17 Jun 2004 14:25:44 -0000 @@ -131,5 +131,14 @@ typedef cyg_uint16 cyg_mempool_status_flag_t; +#if CYGSEM_MEMALLOC_INVOKE_OUTOFMEMORY +// breakpoint site for out of memory conditions +__externC void cyg_memalloc_alloc_fail(); +#else +// this will compile away to nothing with optimisations turned on. +inline void cyg_memalloc_alloc_fail() { +} +#endif + #endif /* ifndef CYGONCE_MEMALLOC_COMMON_HXX */ /* EOF common.hxx */ Index: common/current/include/memjoin.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/memjoin.inl,v retrieving revision 1.6 diff -u -w -r1.6 memjoin.inl --- common/current/include/memjoin.inl 5 Feb 2003 01:10:12 -0000 1.6 +++ common/current/include/memjoin.inl 17 Jun 2004 14:25:45 -0000 @@ -178,6 +178,10 @@ } CYG_REPORT_RETVAL( ptr ); + + if (ptr==NULL) { + cyg_memalloc_alloc_fail(); + } return ptr; } // Cyg_Mempool_Joined<T>::try_alloc() @@ -214,6 +218,7 @@ ret = pool->resize_alloc( alloc_ptr, newsize, oldsize ); CYG_REPORT_RETVAL( ret ); + return ret; } // Cyg_Mempool_Joined<T>::resize_alloc() Index: common/current/include/mempolt2.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mempolt2.inl,v retrieving revision 1.3 diff -u -w -r1.3 mempolt2.inl --- common/current/include/mempolt2.inl 23 May 2002 23:08:43 -0000 1.3 +++ common/current/include/mempolt2.inl 17 Jun 2004 14:25:45 -0000 @@ -116,6 +116,8 @@ Mempolt2WaitInfo waitinfo( size ); + cyg_memalloc_alloc_fail(); + self->set_wait_info( (CYG_ADDRWORD)&waitinfo ); self->set_sleep_reason( Cyg_Thread::WAIT ); self->sleep(); @@ -187,6 +189,9 @@ // straight to unlock. if( Cyg_Thread::NONE == self->get_wake_reason() ) { + + cyg_memalloc_alloc_fail(); + self->set_wait_info( (CYG_ADDRWORD)&waitinfo ); self->sleep(); queue.enqueue( self ); @@ -251,6 +256,11 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } + return ret; } @@ -283,6 +293,11 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } + return ret; } Index: common/current/include/mempoolt.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mempoolt.inl,v retrieving revision 1.3 diff -u -w -r1.3 mempoolt.inl --- common/current/include/mempoolt.inl 23 May 2002 23:08:43 -0000 1.3 +++ common/current/include/mempoolt.inl 17 Jun 2004 14:25:45 -0000 @@ -111,6 +111,9 @@ cyg_uint8 *ret; cyg_bool result = true; while( result && (NULL == (ret = pool.alloc( size ))) ) { + + cyg_memalloc_alloc_fail(); + self->set_sleep_reason( Cyg_Thread::WAIT ); self->sleep(); queue.enqueue( self ); @@ -182,6 +185,8 @@ result = false; while( result && (NULL == (ret = pool.alloc( size ))) ) { + cyg_memalloc_alloc_fail(); + self->set_sleep_reason( Cyg_Thread::TIMEOUT ); self->sleep(); queue.enqueue( self ); @@ -248,6 +253,10 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( ret ); + + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } return ret; } Index: common/current/include/mfiximpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mfiximpl.inl,v retrieving revision 1.3 diff -u -w -r1.3 mfiximpl.inl --- common/current/include/mfiximpl.inl 23 May 2002 23:08:44 -0000 1.3 +++ common/current/include/mfiximpl.inl 17 Jun 2004 14:25:46 -0000 @@ -122,8 +122,10 @@ { // size parameter is not used CYG_UNUSED_PARAM( cyg_int32, size ); - if ( 0 >= freeblocks ) + if ( 0 >= freeblocks ) { + cyg_memalloc_alloc_fail(); return NULL; + } cyg_int32 i = firstfree; cyg_uint8 *p = NULL; do { @@ -172,8 +174,10 @@ if (newsize == blocksize) return alloc_ptr; - else + else { + cyg_memalloc_alloc_fail(); return NULL; + } } // resize_alloc() Index: common/current/include/mvarimpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mvarimpl.inl,v retrieving revision 1.5 diff -u -w -r1.5 mvarimpl.inl --- common/current/include/mvarimpl.inl 23 May 2002 23:08:44 -0000 1.5 +++ common/current/include/mvarimpl.inl 17 Jun 2004 14:25:46 -0000 @@ -275,6 +275,9 @@ cyg_uint8 *ptr = memdq2alloc( dq ); CYG_ASSERT( ((CYG_ADDRESS)ptr & (alignment-1)) == 0, "returned memory not aligned" ); + if (ptr==NULL) { + cyg_memalloc_alloc_fail(); + } return ptr; } @@ -358,6 +361,9 @@ ret = alloc_ptr; } + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } return ret; } // resize_alloc() Index: common/current/include/sepmetaimpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.inl,v retrieving revision 1.4 diff -u -w -r1.4 sepmetaimpl.inl --- common/current/include/sepmetaimpl.inl 23 May 2002 23:08:44 -0000 1.4 +++ common/current/include/sepmetaimpl.inl 17 Jun 2004 14:25:47 -0000 @@ -374,8 +374,10 @@ size = (size + alignment - 1) & -alignment; struct memdq *dq = find_free_dq( size ); - if (NULL == dq) + if (NULL == dq) { + cyg_memalloc_alloc_fail(); return NULL; + } cyg_int32 dqsize = dq->memnext->mem - dq->mem; @@ -399,8 +401,11 @@ // first get a memdq - if ( NULL == freemetahead ) // out of metadata. + if ( NULL == freemetahead ) { + // out of metadata. + cyg_memalloc_alloc_fail(); return NULL; + } // FIXME: since we don't search all the way for an exact fit // first we may be able to find an exact fit later and therefore @@ -496,7 +501,10 @@ prevmemsize = dq->mem - dq->memprev->mem; } if (nextmemsize + prevmemsize + currsize < newsize) + { + cyg_memalloc_alloc_fail(); return NULL; // can't fit it + } // expand forwards if ( nextmemsize != 0 ) { @@ -560,8 +568,10 @@ } else { // if its already allocated we need to create a new free list // entry - if (NULL == freemetahead) + if (NULL == freemetahead) { + cyg_memalloc_alloc_fail(); return NULL; // can't do it + } struct memdq *fdq = freemetahead; freemetahead = fdq->next; Index: common/current/src/dlmalloc.cxx =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/src/dlmalloc.cxx,v retrieving revision 1.8 diff -u -w -r1.8 dlmalloc.cxx --- common/current/src/dlmalloc.cxx 6 Oct 2003 18:25:57 -0000 1.8 +++ common/current/src/dlmalloc.cxx 17 Jun 2004 14:25:48 -0000 @@ -217,6 +217,8 @@ #include <cyg/memalloc/dlmalloc.hxx> //#include <cyg/infra/diag.h> + + /* Debugging: @@ -1273,6 +1275,7 @@ //diag_printf("chunksize(top)=%ld, nb=%d, remainder=%ld\n", chunksize(top), // nb, remainder_size); MALLOC_UNLOCK; + cyg_memalloc_alloc_fail(); return NULL; /* propagate failure */ } @@ -1558,6 +1561,7 @@ // couldn't resize the allocation any direction, so return failure MALLOC_UNLOCK; + cyg_memalloc_alloc_fail(); return NULL; } [-- Attachment #3: Type: text/plain, Size: 148 bytes --] -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [ECOS] New memory allocation debug feature 2004-06-17 14:30 ` Øyvind Harboe @ 2004-06-18 11:58 ` Andrew Lunn 2004-06-18 15:06 ` Øyvind Harboe 0 siblings, 1 reply; 7+ messages in thread From: Andrew Lunn @ 2004-06-18 11:58 UTC (permalink / raw) To: ?yvind Harboe; +Cc: Andrew Lunn, ecos-discuss > > You also need to provide an implementation in libtarget.a for when the > > application does not have such a function. eg all the test programs > > will not provide this function, so will fail to link when your new > > option is enabled. So please add a week function which does nothing, > > or maybe throws an CYG_FAIL(). > > Hmmm... Can this be done without adding a new source file? Can you declare a function using C calling convention in a C++ file? I don't know, im a C programmer. If you can, i suggest you add it to the end of malloc.cxx > > > It would also be nice if you used to same coding style for the patch > > as for the rest of the file, ie { on the same line as the if etc. > > Should be OK now. The patch looks like the indentation is wrong, but that could be that tabs are being shown wrongly. Once we have a patch with a the we[ea]k function i will take a closer look. > My dream is that CVS would automatically enforce all such formatting > rules transparently, and that text editors would present the source code > in the preferred coloring and formatting of the programmer. :-) CVS enforcing it only causes me more problems since i would have to reject more patches. You should try emacs. It does colouring i like and once you have told it what formatting style to use it also does most of the layout work as well. Andrew -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [ECOS] New memory allocation debug feature 2004-06-18 11:58 ` Andrew Lunn @ 2004-06-18 15:06 ` Øyvind Harboe 2004-06-18 21:42 ` Andrew Lunn 0 siblings, 1 reply; 7+ messages in thread From: Øyvind Harboe @ 2004-06-18 15:06 UTC (permalink / raw) To: Andrew Lunn; +Cc: ecos-discuss [-- Attachment #1: Type: text/plain, Size: 849 bytes --] Quoting Andrew Lunn <andrew@lunn.ch>: > > > You also need to provide an implementation in libtarget.a for when the > > > application does not have such a function. eg all the test programs > > > will not provide this function, so will fail to link when your new > > > option is enabled. So please add a week function which does nothing, > > > or maybe throws an CYG_FAIL(). > > > > Hmmm... Can this be done without adding a new source file? > > Can you declare a function using C calling convention in a C++ file? I > don't know, im a C programmer. If you can, i suggest you add it to the > end of malloc.cxx I found it easiest to just add a new debug.cxx file. New patch attached. > > You should try emacs. I use emacs all the time, but from different computers, so I find that I don't want to spend the time configuring it. Ãyvind [-- Attachment #2: memdebug.txt --] [-- Type: text/plain, Size: 10303 bytes --] Index: common/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/ChangeLog,v retrieving revision 1.30 diff -w -u -r1.30 ChangeLog --- common/current/ChangeLog 15 Mar 2004 15:42:04 -0000 1.30 +++ common/current/ChangeLog 18 Jun 2004 15:01:06 -0000 @@ -1,3 +1,8 @@ +2004-06-17 Oyvind Harboe <oyvind.harboe@zylin.com> + + * Added cyg_memalloc_alloc_fail() fn which is invoked before return NULL + from failed allocations. Useful breakpoint site. + 2004-02-15 Jonathan Larmour <jifl@eCosCentric.com> * include/kapi.h: Add throw specifications throughout. Index: common/current/cdl/memalloc.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/cdl/memalloc.cdl,v retrieving revision 1.12 diff -w -u -r1.12 memalloc.cdl --- common/current/cdl/memalloc.cdl 6 Oct 2003 16:41:07 -0000 1.12 +++ common/current/cdl/memalloc.cdl 18 Jun 2004 15:01:06 -0000 @@ -56,7 +56,7 @@ interface. It also contains some sample implementations." include_dir cyg/memalloc compile dlmalloc.cxx memfixed.cxx memvar.cxx \ - sepmeta.cxx + sepmeta.cxx debug.cxx # ==================================================================== @@ -239,6 +239,14 @@ forces a NULL pointer to be returned." } + cdl_option CYGSEM_MEMALLOC_INVOKE_OUTOFMEMORY { + display "invoke user supplied cyg_memalloc_alloc_fail() function when running out of memory" + default_value 0 + description " + Whenever the system runs out of memory, it invokes this function before either + going to sleep(waiting for memory to become available) or returning failure." + } + cdl_component CYGPKG_MEMALLOC_MALLOC_ALLOCATORS { display "malloc() and supporting allocators" flavor bool Index: common/current/include/common.hxx =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/common.hxx,v retrieving revision 1.3 diff -w -u -r1.3 common.hxx --- common/current/include/common.hxx 23 May 2002 23:08:43 -0000 1.3 +++ common/current/include/common.hxx 18 Jun 2004 15:01:14 -0000 @@ -131,5 +131,14 @@ typedef cyg_uint16 cyg_mempool_status_flag_t; +#if CYGSEM_MEMALLOC_INVOKE_OUTOFMEMORY +// breakpoint site for out of memory conditions +__externC void cyg_memalloc_alloc_fail(); +#else +// this will compile away to nothing with optimisations turned on. +inline void cyg_memalloc_alloc_fail() { +} +#endif + #endif /* ifndef CYGONCE_MEMALLOC_COMMON_HXX */ /* EOF common.hxx */ Index: common/current/include/memjoin.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/memjoin.inl,v retrieving revision 1.6 diff -w -u -r1.6 memjoin.inl --- common/current/include/memjoin.inl 5 Feb 2003 01:10:12 -0000 1.6 +++ common/current/include/memjoin.inl 18 Jun 2004 15:01:15 -0000 @@ -178,6 +178,10 @@ } CYG_REPORT_RETVAL( ptr ); + + if (ptr==NULL) { + cyg_memalloc_alloc_fail(); + } return ptr; } // Cyg_Mempool_Joined<T>::try_alloc() @@ -214,6 +218,7 @@ ret = pool->resize_alloc( alloc_ptr, newsize, oldsize ); CYG_REPORT_RETVAL( ret ); + return ret; } // Cyg_Mempool_Joined<T>::resize_alloc() Index: common/current/include/mempolt2.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mempolt2.inl,v retrieving revision 1.3 diff -w -u -r1.3 mempolt2.inl --- common/current/include/mempolt2.inl 23 May 2002 23:08:43 -0000 1.3 +++ common/current/include/mempolt2.inl 18 Jun 2004 15:01:15 -0000 @@ -116,6 +116,8 @@ Mempolt2WaitInfo waitinfo( size ); + cyg_memalloc_alloc_fail(); + self->set_wait_info( (CYG_ADDRWORD)&waitinfo ); self->set_sleep_reason( Cyg_Thread::WAIT ); self->sleep(); @@ -187,6 +189,9 @@ // straight to unlock. if( Cyg_Thread::NONE == self->get_wake_reason() ) { + + cyg_memalloc_alloc_fail(); + self->set_wait_info( (CYG_ADDRWORD)&waitinfo ); self->sleep(); queue.enqueue( self ); @@ -251,6 +256,11 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } + return ret; } @@ -283,6 +293,11 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } + return ret; } Index: common/current/include/mempoolt.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mempoolt.inl,v retrieving revision 1.3 diff -w -u -r1.3 mempoolt.inl --- common/current/include/mempoolt.inl 23 May 2002 23:08:43 -0000 1.3 +++ common/current/include/mempoolt.inl 18 Jun 2004 15:01:16 -0000 @@ -111,6 +111,9 @@ cyg_uint8 *ret; cyg_bool result = true; while( result && (NULL == (ret = pool.alloc( size ))) ) { + + cyg_memalloc_alloc_fail(); + self->set_sleep_reason( Cyg_Thread::WAIT ); self->sleep(); queue.enqueue( self ); @@ -182,6 +185,8 @@ result = false; while( result && (NULL == (ret = pool.alloc( size ))) ) { + cyg_memalloc_alloc_fail(); + self->set_sleep_reason( Cyg_Thread::TIMEOUT ); self->sleep(); queue.enqueue( self ); @@ -248,6 +253,10 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( ret ); + + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } return ret; } Index: common/current/include/mfiximpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mfiximpl.inl,v retrieving revision 1.3 diff -w -u -r1.3 mfiximpl.inl --- common/current/include/mfiximpl.inl 23 May 2002 23:08:44 -0000 1.3 +++ common/current/include/mfiximpl.inl 18 Jun 2004 15:01:16 -0000 @@ -122,8 +122,10 @@ { // size parameter is not used CYG_UNUSED_PARAM( cyg_int32, size ); - if ( 0 >= freeblocks ) + if ( 0 >= freeblocks ) { + cyg_memalloc_alloc_fail(); return NULL; + } cyg_int32 i = firstfree; cyg_uint8 *p = NULL; do { @@ -172,8 +174,10 @@ if (newsize == blocksize) return alloc_ptr; - else + else { + cyg_memalloc_alloc_fail(); return NULL; + } } // resize_alloc() Index: common/current/include/mvarimpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mvarimpl.inl,v retrieving revision 1.5 diff -w -u -r1.5 mvarimpl.inl --- common/current/include/mvarimpl.inl 23 May 2002 23:08:44 -0000 1.5 +++ common/current/include/mvarimpl.inl 18 Jun 2004 15:01:16 -0000 @@ -275,6 +275,9 @@ cyg_uint8 *ptr = memdq2alloc( dq ); CYG_ASSERT( ((CYG_ADDRESS)ptr & (alignment-1)) == 0, "returned memory not aligned" ); + if (ptr==NULL) { + cyg_memalloc_alloc_fail(); + } return ptr; } @@ -358,6 +361,9 @@ ret = alloc_ptr; } + if (ret==NULL) { + cyg_memalloc_alloc_fail(); + } return ret; } // resize_alloc() Index: common/current/include/sepmetaimpl.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.inl,v retrieving revision 1.4 diff -w -u -r1.4 sepmetaimpl.inl --- common/current/include/sepmetaimpl.inl 23 May 2002 23:08:44 -0000 1.4 +++ common/current/include/sepmetaimpl.inl 18 Jun 2004 15:01:17 -0000 @@ -374,8 +374,10 @@ size = (size + alignment - 1) & -alignment; struct memdq *dq = find_free_dq( size ); - if (NULL == dq) + if (NULL == dq) { + cyg_memalloc_alloc_fail(); return NULL; + } cyg_int32 dqsize = dq->memnext->mem - dq->mem; @@ -399,8 +401,11 @@ // first get a memdq - if ( NULL == freemetahead ) // out of metadata. + if ( NULL == freemetahead ) { + // out of metadata. + cyg_memalloc_alloc_fail(); return NULL; + } // FIXME: since we don't search all the way for an exact fit // first we may be able to find an exact fit later and therefore @@ -496,7 +501,10 @@ prevmemsize = dq->mem - dq->memprev->mem; } if (nextmemsize + prevmemsize + currsize < newsize) + { + cyg_memalloc_alloc_fail(); return NULL; // can't fit it + } // expand forwards if ( nextmemsize != 0 ) { @@ -560,8 +568,10 @@ } else { // if its already allocated we need to create a new free list // entry - if (NULL == freemetahead) + if (NULL == freemetahead) { + cyg_memalloc_alloc_fail(); return NULL; // can't do it + } struct memdq *fdq = freemetahead; freemetahead = fdq->next; Index: common/current/src/dlmalloc.cxx =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/src/dlmalloc.cxx,v retrieving revision 1.8 diff -w -u -r1.8 dlmalloc.cxx --- common/current/src/dlmalloc.cxx 6 Oct 2003 18:25:57 -0000 1.8 +++ common/current/src/dlmalloc.cxx 18 Jun 2004 15:01:18 -0000 @@ -217,6 +217,8 @@ #include <cyg/memalloc/dlmalloc.hxx> //#include <cyg/infra/diag.h> + + /* Debugging: @@ -1273,6 +1275,7 @@ //diag_printf("chunksize(top)=%ld, nb=%d, remainder=%ld\n", chunksize(top), // nb, remainder_size); MALLOC_UNLOCK; + cyg_memalloc_alloc_fail(); return NULL; /* propagate failure */ } @@ -1558,6 +1561,7 @@ // couldn't resize the allocation any direction, so return failure MALLOC_UNLOCK; + cyg_memalloc_alloc_fail(); return NULL; } [-- Attachment #3: debug.cxx --] [-- Type: text/plain, Size: 2842 bytes --] //======================================================================== // // debug.cxx // // default implementation of out of memory debug breakpoint site // //======================================================================== //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 or (at your option) any later version. // // eCos is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License along // with eCos; if not, write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. // // As a special exception, if other files instantiate templates or use macros // or inline functions from this file, or you compile this file and link it // with other works to produce a work based on this file, this file does not // by itself cause the resulting work to be covered by the GNU General Public // License. However the source code for this file must still be made available // in accordance with section (3) of the GNU General Public License. // // This exception does not invalidate any other reasons why a work based on // this file might be covered by the GNU General Public License. // // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. // at http://sources.redhat.com/ecos/ecos-license/ // ------------------------------------------- //####ECOSGPLCOPYRIGHTEND#### //======================================================================== //#####DESCRIPTIONBEGIN#### // // Author(s): oyvind // Contributors: // Date: 2000-06-17 // Purpose: // Description: Memory usage debugging // Usage: // //####DESCRIPTIONEND#### // //======================================================================== // CONFIGURATION #include <pkgconf/memalloc.h> // Configuration header #include <cyg/infra/cyg_type.h> // Common type definitions and support #include <cyg/infra/cyg_trac.h> // Common tracing support #include <cyg/infra/cyg_ass.h> // Common assertion support #include <string.h> // For memset() and memmove() #include <stdlib.h> // header for this file #if CYGSEM_MEMALLOC_INVOKE_OUTOFMEMORY __externC void cyg_memalloc_alloc_fail() { // handy breakpoint site. } #endif // EOF debug.cxx [-- Attachment #4: Type: text/plain, Size: 148 bytes --] -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [ECOS] New memory allocation debug feature 2004-06-18 15:06 ` Øyvind Harboe @ 2004-06-18 21:42 ` Andrew Lunn 0 siblings, 0 replies; 7+ messages in thread From: Andrew Lunn @ 2004-06-18 21:42 UTC (permalink / raw) To: ?yvind Harboe; +Cc: Andrew Lunn, ecos-discuss > New patch attached. Thanks I started to look at the patch, but decided there are a number of things i don't like. There should be a prototype for cyg_memalloc_alloc_fail() in one of the normal header file so that user code can use it. You put it into common.hxx which is wrong. Application code is not supposed to use the C++ API. I would add something like __externC void cyg_memalloc_alloc_fail(char * file, int line, cyg_int32 size) __THROW __CYG_ATTRIBUTE_WEAK; to services/memalloc/common/current/include/kapi.h. This should not be conditional, since the application code should be able to have the function even if eCos is not configured to use it. But this then leads to a problem with the code in common.hxx. You make the function an empty inline function when CYSEM_MEMALLOC_INVOKE_OUT_OF_MEMORY is disabled, assuming the optimizer will optimize out the function call and the test to see if the ptr is NULL. But you cannot have the function both __externC void and inline void. The compiler should complain. Im also not sure the optimizer is that smart. And since the empty inline is the normal case, we don't want none optimal code here. So i would suggest putting something like this in common.hxx #ifdef CYSEM_MEMALLOC_INVOKE_OUT_OF_MEMORY #define CYG_MEMALLOC_FAIL_TEST( ptr, size) \ CYG_MACRO_BEGIN \ if ( NULL == ptr) { \ cyg_malloc_fail(__FILE__, __LINE__, size ); \ } \ CYG_MACRO_END #else #define CYG_MEMALLOC_FAIL_TEST( ptr, size) CYG_EMPTY_STATEMENT #endif Then change all your tests to calls to the MACRO. You debug.cxx should really debug.c You want a C function so you might as well use the C compiler not the C++ compiler. The function needs updating the take the paramters i've suggested. You also didn't make it a weak funcion like i asked. A few other minor things. CYSEM_MEMALLOC_INVOKE_OUTOFMEMORY should be CYSEM_MEMALLOC_INVOKE_OUT_OF_MEMORY, following the same naming convention as cyg_memalloc_alloc_failed. ie "_" between words. Also its normal to not have lines longer than around 78 charactors in eCos files. Both your changes to memalloc.cdl and ChangeLog had lines which were too long. > > > > You should try emacs. > > I use emacs all the time, but from different computers, so I find that I don't > want to spend the time configuring it. One little trick i've seen people use is to checking all their .rc files into CVS. When change something on one machine, check it in and then cvs up on all the other machines. Alternativly, just have you home directory on a network drive which all machines use. Andrew -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2004-06-18 21:42 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-06-17 10:55 [ECOS] New memory allocation debug feature Øyvind Harboe 2004-06-17 12:10 ` Andrew Lunn 2004-06-17 13:01 ` Nick Garnett 2004-06-17 14:30 ` Øyvind Harboe 2004-06-18 11:58 ` Andrew Lunn 2004-06-18 15:06 ` Øyvind Harboe 2004-06-18 21:42 ` Andrew Lunn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).