new memory debug feature
Andrew Lunn
andrew@lunn.ch
Thu Jul 1 14:51:00 GMT 2004
> There are quite a lot of functions with weak attributes scattered
> around the sources. Take a look, for example, at hal_spurious_IRQ() in
> the ARM architecture HAL. There certainly shouldn't be any compiler
> problems in this area, it's platform independent and has been working
> for years.
I had the syntax wrong :-(
Anyway, here i what i think is the final version. I've compiled it for
synth and run the memalloc tests and compiled both default and redboot
template for the edb7xxx without problems.
Andrew
-------------- next part --------------
? services/memalloc/common/current/src/debug.c
Index: services/memalloc/common/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/ChangeLog,v
retrieving revision 1.30
diff -u -r1.30 ChangeLog
--- services/memalloc/common/current/ChangeLog 15 Mar 2004 15:42:04 -0000 1.30
+++ services/memalloc/common/current/ChangeLog 1 Jul 2004 14:49:10 -0000
@@ -1,3 +1,10 @@
+2004-06-24 Oyvind Harboe <oyvind.harboe@zylin.com>
+
+ * 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 <jifl@eCosCentric.com>
* include/kapi.h: Add throw specifications throughout.
Index: services/memalloc/common/current/cdl/memalloc.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/cdl/memalloc.cdl,v
retrieving revision 1.12
diff -u -r1.12 memalloc.cdl
--- services/memalloc/common/current/cdl/memalloc.cdl 6 Oct 2003 16:41:07 -0000 1.12
+++ services/memalloc/common/current/cdl/memalloc.cdl 1 Jul 2004 14:49:11 -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: services/memalloc/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 -r1.3 common.hxx
--- services/memalloc/common/current/include/common.hxx 23 May 2002 23:08:43 -0000 1.3
+++ services/memalloc/common/current/include/common.hxx 1 Jul 2004 14:49:12 -0000
@@ -130,6 +130,23 @@
// And an opaque type for any arguments with these flags
typedef cyg_uint16 cyg_mempool_status_flag_t;
+// breakpoint site for out of memory conditions
+#ifdef CYGSEM_MEMALLOC_INVOKE_OUT_OF_MEMORY
+#include <cyg/memalloc/kapi.h> // protoype for cyg_memalloc_alloc_fail
+#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: services/memalloc/common/current/include/kapi.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/kapi.h,v
retrieving revision 1.4
diff -u -r1.4 kapi.h
--- services/memalloc/common/current/include/kapi.h 15 Mar 2004 15:42:04 -0000 1.4
+++ services/memalloc/common/current/include/kapi.h 1 Jul 2004 14:49:12 -0000
@@ -58,11 +58,23 @@
//========================================================================*/
/* CONFIGURATION */
-
+#include <pkgconf/system.h>
#include <pkgconf/memalloc.h>
/* TYPE DEFINITIONS */
+#ifdef CYGPKG_KERNEL
+#include <cyg/kernel/kapi.h>
+#else
+typedef cyg_uint32 cyg_handle_t;
+#endif
+/*---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
struct cyg_mempool_var;
typedef struct cyg_mempool_var cyg_mempool_var;
@@ -176,6 +188,16 @@
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;
+
+/*---------------------------------------------------------------------------*/
+#ifdef __cplusplus
+}
+#endif
+
+/*---------------------------------------------------------------------------*/
#endif /* ifndef CYGONCE_MEMALLOC_KAPI_H */
Index: services/memalloc/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 -r1.6 memjoin.inl
--- services/memalloc/common/current/include/memjoin.inl 5 Feb 2003 01:10:12 -0000 1.6
+++ services/memalloc/common/current/include/memjoin.inl 1 Jul 2004 14:49:12 -0000
@@ -178,6 +178,9 @@
}
CYG_REPORT_RETVAL( ptr );
+
+ CYG_MEMALLOC_FAIL_TEST(ptr==NULL, size);
+
return ptr;
} // Cyg_Mempool_Joined<T>::try_alloc()
@@ -214,6 +217,7 @@
ret = pool->resize_alloc( alloc_ptr, newsize, oldsize );
CYG_REPORT_RETVAL( ret );
+
return ret;
} // Cyg_Mempool_Joined<T>::resize_alloc()
Index: services/memalloc/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 -r1.3 mempolt2.inl
--- services/memalloc/common/current/include/mempolt2.inl 23 May 2002 23:08:43 -0000 1.3
+++ services/memalloc/common/current/include/mempolt2.inl 1 Jul 2004 14:49:13 -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: services/memalloc/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 -r1.3 mempoolt.inl
--- services/memalloc/common/current/include/mempoolt.inl 23 May 2002 23:08:43 -0000 1.3
+++ services/memalloc/common/current/include/mempoolt.inl 1 Jul 2004 14:49:14 -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: services/memalloc/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 -r1.3 mfiximpl.inl
--- services/memalloc/common/current/include/mfiximpl.inl 23 May 2002 23:08:44 -0000 1.3
+++ services/memalloc/common/current/include/mfiximpl.inl 1 Jul 2004 14:49:14 -0000
@@ -59,6 +59,7 @@
#include <cyg/hal/hal_arch.h> // HAL_LSBIT_INDEX magic asm code
#include <cyg/memalloc/mfiximpl.hxx>
+
// -------------------------------------------------------------------------
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: services/memalloc/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 -r1.5 mvarimpl.inl
--- services/memalloc/common/current/include/mvarimpl.inl 23 May 2002 23:08:44 -0000 1.5
+++ services/memalloc/common/current/include/mvarimpl.inl 1 Jul 2004 14:49:15 -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: services/memalloc/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 -r1.4 sepmetaimpl.inl
--- services/memalloc/common/current/include/sepmetaimpl.inl 23 May 2002 23:08:44 -0000 1.4
+++ services/memalloc/common/current/include/sepmetaimpl.inl 1 Jul 2004 14:49:16 -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: services/memalloc/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 -r1.8 dlmalloc.cxx
--- services/memalloc/common/current/src/dlmalloc.cxx 6 Oct 2003 18:25:57 -0000 1.8
+++ services/memalloc/common/current/src/dlmalloc.cxx 1 Jul 2004 14:49:19 -0000
@@ -215,7 +215,6 @@
#include <cyg/infra/cyg_ass.h> // assertions
#include <stddef.h> // for size_t
#include <cyg/memalloc/dlmalloc.hxx>
-//#include <cyg/infra/diag.h>
/*
Debugging:
@@ -1273,6 +1272,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 +1558,7 @@
// couldn't resize the allocation any direction, so return failure
MALLOC_UNLOCK;
+ CYG_MEMALLOC_FAIL(bytes);
return NULL;
}
More information about the Ecos-patches
mailing list