public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [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).