? src/debug.c Index: ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/ChangeLog,v retrieving revision 1.30 diff -u -w -r1.30 ChangeLog --- ChangeLog 15 Mar 2004 15:42:04 -0000 1.30 +++ ChangeLog 1 Jul 2004 07:59:50 -0000 @@ -1,3 +1,10 @@ +2004-06-24 Oyvind Harboe + + * Added cyg_memalloc_alloc_fail() fn which is invoked before + return NULL from failed allocations. Useful breakpoint site. + Andrew Lunn wrote some of the code and pointed out various + wrinkles to be ironed out. + 2004-02-15 Jonathan Larmour * 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 -u -w -r1.12 memalloc.cdl --- cdl/memalloc.cdl 6 Oct 2003 16:41:07 -0000 1.12 +++ cdl/memalloc.cdl 1 Jul 2004 07:59:50 -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.c # ==================================================================== @@ -239,6 +239,15 @@ forces a NULL pointer to be returned." } + cdl_option CYGSEM_MEMALLOC_INVOKE_OUT_OF_MEMORY { + display "Breakpoint site 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 -u -w -r1.3 common.hxx --- include/common.hxx 23 May 2002 23:08:43 -0000 1.3 +++ include/common.hxx 1 Jul 2004 07:59:50 -0000 @@ -57,6 +57,8 @@ /* CONFIGURATION */ +#include // required for cyg_handle_t +#include #include /* TYPE DEFINITIONS */ @@ -131,5 +133,23 @@ typedef cyg_uint16 cyg_mempool_status_flag_t; +// breakpoint site for out of memory conditions + +#ifdef CYGSEM_MEMALLOC_INVOKE_OUT_OF_MEMORY +#define CYG_MEMALLOC_FAIL_TEST( test, size ) \ + CYG_MACRO_START \ + if ( test) { \ + cyg_memalloc_alloc_fail(__FILE__, __LINE__, size ); \ + } \ + CYG_MACRO_END +#define CYG_MEMALLOC_FAIL( size) \ + CYG_MACRO_START \ + cyg_memalloc_alloc_fail(__FILE__, __LINE__, size ); \ + CYG_MACRO_END +#else +#define CYG_MEMALLOC_FAIL_TEST( test, size ) CYG_EMPTY_STATEMENT +#define CYG_MEMALLOC_FAIL( size ) CYG_EMPTY_STATEMENT +#endif + #endif /* ifndef CYGONCE_MEMALLOC_COMMON_HXX */ /* EOF common.hxx */ Index: include/kapi.h =================================================================== RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/kapi.h,v retrieving revision 1.4 diff -u -w -r1.4 kapi.h --- include/kapi.h 15 Mar 2004 15:42:04 -0000 1.4 +++ include/kapi.h 1 Jul 2004 07:59:50 -0000 @@ -176,7 +176,9 @@ provided. */ void cyg_mempool_fix_get_info(cyg_handle_t fixpool, cyg_mempool_info *info) __THROW; - +/* user overrideable function invoked before running out of memory. */ +__externC void cyg_memalloc_alloc_fail(char * file, int line, cyg_int32 size) + __THROW; #endif /* ifndef CYGONCE_MEMALLOC_KAPI_H */ /* EOF kapi.h */ Index: 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 --- include/memjoin.inl 5 Feb 2003 01:10:12 -0000 1.6 +++ include/memjoin.inl 1 Jul 2004 07:59:51 -0000 @@ -178,6 +178,9 @@ } CYG_REPORT_RETVAL( ptr ); + + CYG_MEMALLOC_FAIL_TEST(ptr==NULL, size); + return ptr; } // Cyg_Mempool_Joined::try_alloc() @@ -214,6 +217,7 @@ ret = pool->resize_alloc( alloc_ptr, newsize, oldsize ); CYG_REPORT_RETVAL( ret ); + return ret; } // Cyg_Mempool_Joined::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 -u -w -r1.3 mempolt2.inl --- include/mempolt2.inl 23 May 2002 23:08:43 -0000 1.3 +++ include/mempolt2.inl 1 Jul 2004 07:59:51 -0000 @@ -116,6 +116,8 @@ Mempolt2WaitInfo waitinfo( size ); + CYG_MEMALLOC_FAIL(size); + 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_FAIL(size); + self->set_wait_info( (CYG_ADDRWORD)&waitinfo ); self->sleep(); queue.enqueue( self ); @@ -251,6 +256,9 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + CYG_MEMALLOC_FAIL_TEST(ret==NULL, size); + return ret; } @@ -283,6 +291,9 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + + CYG_MEMALLOC_FAIL_TEST(ret==NULL, newsize); + 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 -u -w -r1.3 mempoolt.inl --- include/mempoolt.inl 23 May 2002 23:08:43 -0000 1.3 +++ include/mempoolt.inl 1 Jul 2004 07:59:51 -0000 @@ -111,6 +111,9 @@ cyg_uint8 *ret; cyg_bool result = true; while( result && (NULL == (ret = pool.alloc( size ))) ) { + + CYG_MEMALLOC_FAIL(size); + 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_FAIL(size); + self->set_sleep_reason( Cyg_Thread::TIMEOUT ); self->sleep(); queue.enqueue( self ); @@ -248,6 +253,9 @@ // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( ret ); + + CYG_MEMALLOC_FAIL_TEST(ret==NULL, size); + 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 -u -w -r1.3 mfiximpl.inl --- include/mfiximpl.inl 23 May 2002 23:08:44 -0000 1.3 +++ include/mfiximpl.inl 1 Jul 2004 07:59:51 -0000 @@ -59,6 +59,7 @@ #include // HAL_LSBIT_INDEX magic asm code #include + // ------------------------------------------------------------------------- inline @@ -122,8 +123,10 @@ { // size parameter is not used CYG_UNUSED_PARAM( cyg_int32, size ); - if ( 0 >= freeblocks ) + if ( 0 >= freeblocks ) { + CYG_MEMALLOC_FAIL(size); return NULL; + } cyg_int32 i = firstfree; cyg_uint8 *p = NULL; do { @@ -172,8 +175,10 @@ if (newsize == blocksize) return alloc_ptr; - else + else { + CYG_MEMALLOC_FAIL(newsize); 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 -u -w -r1.5 mvarimpl.inl --- include/mvarimpl.inl 23 May 2002 23:08:44 -0000 1.5 +++ include/mvarimpl.inl 1 Jul 2004 07:59:52 -0000 @@ -275,6 +275,8 @@ cyg_uint8 *ptr = memdq2alloc( dq ); CYG_ASSERT( ((CYG_ADDRESS)ptr & (alignment-1)) == 0, "returned memory not aligned" ); + CYG_MEMALLOC_FAIL_TEST(ptr==NULL, size); + return ptr; } @@ -358,6 +360,8 @@ ret = alloc_ptr; } + CYG_MEMALLOC_FAIL_TEST(ret==NULL, newsize); + 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 -u -w -r1.4 sepmetaimpl.inl --- include/sepmetaimpl.inl 23 May 2002 23:08:44 -0000 1.4 +++ include/sepmetaimpl.inl 1 Jul 2004 07:59:52 -0000 @@ -374,8 +374,12 @@ size = (size + alignment - 1) & -alignment; struct memdq *dq = find_free_dq( size ); - if (NULL == dq) + + + if (NULL == dq) { + CYG_MEMALLOC_FAIL(size); return NULL; + } cyg_int32 dqsize = dq->memnext->mem - dq->mem; @@ -399,8 +403,11 @@ // first get a memdq - if ( NULL == freemetahead ) // out of metadata. + if ( NULL == freemetahead ) { + // out of metadata. + CYG_MEMALLOC_FAIL(size); 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 +503,10 @@ prevmemsize = dq->mem - dq->memprev->mem; } if (nextmemsize + prevmemsize + currsize < newsize) + { + CYG_MEMALLOC_FAIL_TEST(true, newsize); return NULL; // can't fit it + } // expand forwards if ( nextmemsize != 0 ) { @@ -560,8 +570,10 @@ } else { // if its already allocated we need to create a new free list // entry - if (NULL == freemetahead) + if (NULL == freemetahead) { + CYG_MEMALLOC_FAIL(newsize); 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 -u -w -r1.8 dlmalloc.cxx --- src/dlmalloc.cxx 6 Oct 2003 18:25:57 -0000 1.8 +++ src/dlmalloc.cxx 1 Jul 2004 07:59:53 -0000 @@ -215,7 +215,7 @@ #include // assertions #include // for size_t #include -//#include +#include /* Debugging: @@ -1273,6 +1273,7 @@ //diag_printf("chunksize(top)=%ld, nb=%d, remainder=%ld\n", chunksize(top), // nb, remainder_size); MALLOC_UNLOCK; + CYG_MEMALLOC_FAIL(bytes); return NULL; /* propagate failure */ } @@ -1558,6 +1559,7 @@ // couldn't resize the allocation any direction, so return failure MALLOC_UNLOCK; + CYG_MEMALLOC_FAIL(bytes); return NULL; }