callback functionality for dyanmic memory allocation
NavEcos
ecos@navosha.com
Sat Nov 2 04:25:00 GMT 2002
The following patches allows a user to track:
1) heap creation
2) heap destruction
3) allocation/freeing of dynamic memory
and
4) reallocation of dynamic memory (i.e. realloc functionality)
Included is the CDL to control it. By default it is turned off. There will
be a performance penalty to turn on the logging ability even if you do not
use it since a pointer must be checked (the callback).
Example usage is:
// varriable sized heaps
Cyg_Mempool_Variable::set_create_cb (var_create);
Cyg_Mempool_Variable::set_destroy_cb (var_destroy);
Cyg_Mempool_Variable::set_pre_alloc_cb (var_pre_alloc);
Cyg_Mempool_Variable::set_post_alloc_cb (var_post_alloc);
Cyg_Mempool_Variable::set_pre_free_cb (var_pre_free);
Cyg_Mempool_Variable::set_post_free_cb (var_post_free);
// dlmalloc heaps
Cyg_Mempool_dlmalloc::set_create_cb (var_create);
Cyg_Mempool_dlmalloc::set_destroy_cb (var_destroy);
Cyg_Mempool_dlmalloc::set_pre_alloc_cb (var_pre_alloc);
Cyg_Mempool_dlmalloc::set_post_alloc_cb (var_post_alloc);
Cyg_Mempool_dlmalloc::set_pre_free_cb (var_pre_free);
Cyg_Mempool_dlmalloc::set_post_free_cb (var_post_free);
// fixed size block allocator heaps
Cyg_Mempool_Fixed::set_create_cb (fix_create);
Cyg_Mempool_Fixed::set_destroy_cb (fix_destroy);
Cyg_Mempool_Fixed::set_pre_alloc_cb (fix_pre_alloc);
Cyg_Mempool_Fixed::set_post_alloc_cb (fix_post_alloc);
Cyg_Mempool_Fixed::set_pre_free_cb (fix_pre_free);
Cyg_Mempool_Fixed::set_post_free_cb (fix_post_free);
The additional functionality will allow a user to keep track of every
allocation in the system, as well as to modify allocated memory to add
padding to detect array overflows.
Diff files attached.
-Rich
-------------- next part --------------
? cdl/memalloc.cdl_new
Index: cdl/memalloc.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/cdl/memalloc.cdl,v
retrieving revision 1.11
diff -u -r1.11 memalloc.cdl
--- cdl/memalloc.cdl 23 May 2002 23:08:42 -0000 1.11
+++ cdl/memalloc.cdl 2 Nov 2002 12:16:49 -0000
@@ -86,6 +86,17 @@
are made available that allow a thread to wait
until memory is available."
}
+
+ cdl_option CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK {
+ display "Allow registered callbacks"
+ active_if CYGPKG_KERNEL
+ default_value 0
+ description "
+ With this option enabled, this allocator will be
+ able to make calls to callback functions. With this
+ enabled you can track heap creations, destroys,
+ allocations, reallocations and frees"
+ }
}
cdl_component CYGPKG_MEMALLOC_ALLOCATOR_VARIABLE {
@@ -121,6 +132,17 @@
memory fragmentation problems, but involves extra code and
processor cycles."
}
+
+ cdl_option CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK {
+ display "Allow registered callbacks"
+ active_if CYGPKG_KERNEL
+ default_value 0
+ description "
+ With this option enabled, this allocator will be
+ able to make calls to callback functions. With this
+ enabled you can track heap creations, destroys,
+ allocations, reallocations and frees"
+ }
}
cdl_component CYGPKG_MEMALLOC_ALLOCATOR_DLMALLOC {
@@ -174,7 +196,7 @@
silently enabled."
}
- cdl_option CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_USE_MEMCPY {
+ cdl_option CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_USE_MEMCPY {
display "Use system memcpy() and memset()"
requires CYGPKG_ISOINFRA
default_value { 0 != CYGPKG_ISOINFRA }
@@ -183,7 +205,19 @@
are used within the implementation. The alternative is
to use some macro equivalents, which some people report
are faster in some circumstances."
- }
+ }
+
+ cdl_option CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK {
+ display "Allow registered callbacks"
+ active_if CYGPKG_KERNEL
+ default_value 0
+ description "
+ With this option enabled, this allocator will be
+ able to make calls to callback functions. With this
+ enabled you can track heap creations, destroys,
+ allocations, reallocations and frees"
+ }
+
}
cdl_component CYGPKG_MEMALLOC_ALLOCATOR_SEPMETA {
Index: include/dlmalloc.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/dlmalloc.hxx,v
retrieving revision 1.3
diff -u -r1.3 dlmalloc.hxx
--- include/dlmalloc.hxx 23 May 2002 23:08:43 -0000 1.3
+++ include/dlmalloc.hxx 2 Nov 2002 12:16:49 -0000
@@ -91,9 +91,42 @@
// TYPE DEFINITIONS
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+// memory callback functionality
+class Cyg_Mempool_dlmalloc;
+typedef void fn_dl_create
+ (Cyg_Mempool_dlmalloc *pool, const cyg_uint8 *base_ptr, cyg_int32 size);
+typedef void fn_dl_destroy
+ (Cyg_Mempool_dlmalloc *pool, const cyg_uint8 *base_ptr, cyg_int32 size);
+typedef void fn_dl_pre_alloc
+ (Cyg_Mempool_dlmalloc *pool, cyg_int32 *size);
+typedef void fn_dl_post_alloc
+ (Cyg_Mempool_dlmalloc *pool, cyg_uint8 **mem_ptr, cyg_int32 size);
+typedef void fn_dl_pre_realloc
+ (Cyg_Mempool_dlmalloc *pool, cyg_uint8 **mem_ptr, cyg_int32 *newsize,
+ cyg_int32 oldsize);
+typedef void fn_dl_post_realloc
+ (Cyg_Mempool_dlmalloc *pool, cyg_uint8 **mem_ptr, cyg_int32 size);
+typedef void fn_dl_pre_free
+ (Cyg_Mempool_dlmalloc *pool, cyg_uint8 **mem_ptr, cyg_int32 *psize);
+typedef void fn_dl_post_free
+ (Cyg_Mempool_dlmalloc *pool, cyg_uint8 *mem_ptr, cyg_int32 size);
+#endif
class Cyg_Mempool_dlmalloc
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+private:
+ static fn_dl_create *fn_create_cb;
+ static fn_dl_destroy *fn_destroy_cb;
+ static fn_dl_pre_alloc *fn_pre_alloc_cb;
+ static fn_dl_post_alloc *fn_post_alloc_cb;
+ static fn_dl_pre_realloc *fn_pre_realloc_cb;
+ static fn_dl_post_realloc *fn_post_realloc_cb;
+ static fn_dl_pre_free *fn_pre_free_cb;
+ static fn_dl_post_free *fn_post_free_cb;
+#endif
+
protected:
#ifdef CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_THREADAWARE
Cyg_Mempolt2<Cyg_Mempool_dlmalloc_Implementation> mypool;
@@ -108,29 +141,102 @@
// same arena.
Cyg_Mempool_dlmalloc( cyg_uint8 *base, cyg_int32 size,
CYG_ADDRWORD argthru=0 )
- : mypool( base, size, argthru ) {}
+ : mypool( base, size, argthru ) {
+# ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+void test_fun (void); test_fun ();
+ if ( fn_create_cb != NULL ) {
+ (*fn_create_cb) (this, base, size);
+ }
+# endif
+ }
// Destructor
- ~Cyg_Mempool_dlmalloc() {}
+ ~Cyg_Mempool_dlmalloc() {
+# ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+ if ( fn_destroy_cb != NULL ) {
+ Cyg_Mempool_Status status;
+ mypool.get_status (
+ CYG_MEMPOOL_STAT_ORIGBASE
+ | CYG_MEMPOOL_STAT_ORIGSIZE,
+ status );
+ (*fn_destroy_cb) (this,status.origbase, status.origsize);
+ }
+# endif
+ }
// get some memory; wait if none available
// if we aren't configured to be thread-aware this is irrelevant
#ifdef CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_THREADAWARE
cyg_uint8 *
- alloc( cyg_int32 size ) { return mypool.alloc( size ); }
+ alloc( cyg_int32 size ) {
+# ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this, &size);
+ }
+
+ pRet = mypool.alloc( size );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet, size);
+ }
+
+ return pRet;
+# else
+ return mypool.alloc( size );
+# endif
+ }
# ifdef CYGFUN_KERNEL_THREADS_TIMER
// get some memory with a timeout
cyg_uint8 *
alloc( cyg_int32 size, cyg_tick_count delay_timeout ) {
+# ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this, &size);
+ }
+
+ pRet = mypool.alloc( size, delay_timeout );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet, size);
+ }
+
+ return pRet;
+# else
return mypool.alloc( size, delay_timeout );
+# endif
}
# endif
#endif
// get some memory, return NULL if none available
cyg_uint8 *
- try_alloc( cyg_int32 size ) { return mypool.try_alloc( size ); }
+ try_alloc( cyg_int32 size ) {
+# ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this, &size);
+ }
+
+ pRet = mypool.try_alloc( size );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet, size);
+ }
+
+ return pRet;
+# else
+ return mypool.try_alloc( size );
+# endif
+ }
// resize existing allocation, if oldsize is non-NULL, previous
@@ -146,13 +252,59 @@
cyg_uint8 *
resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
cyg_int32 *oldsize ) {
+# ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+ cyg_uint8
+ *pRet;
+ cyg_int32
+ originalsize;
+
+ // get the original size of the block of memory
+ originalsize = mypool.addr2size (alloc_ptr);
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_realloc_cb) (this, &alloc_ptr, &newsize, originalsize);
+ }
+
+ pRet = mypool.resize_alloc( alloc_ptr, newsize, oldsize);
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_realloc_cb) (this, &pRet, newsize);
+ }
+
+ return pRet;
+# else
return mypool.resize_alloc( alloc_ptr, newsize, oldsize);
+# endif
}
// free the memory back to the pool
// returns true on success
cyg_bool
- free( cyg_uint8 *ptr, cyg_int32 size=0 ) { return mypool.free(ptr, size); }
+ free( cyg_uint8 *ptr, cyg_int32 size=0 ) {
+# ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+ cyg_bool
+ b_Ret;
+
+ if ( 0 == size ) {
+ // if the size wasn't given specifically get it from the pointer
+ size = mypool.addr2size (ptr);
+ }
+
+ if ( fn_pre_free_cb != NULL ) {
+ (*fn_pre_free_cb) (this, &ptr, &size);
+ }
+
+ b_Ret = mypool.free(ptr, size);
+
+ if ( fn_post_free_cb != NULL ) {
+ (*fn_post_free_cb) (this, ptr, size);
+ }
+
+ return b_Ret;
+# else
+ return mypool.free(ptr, size);
+# endif
+ }
// Get memory pool status
// flags is a bitmask of requested fields to fill in. The flags are
@@ -164,6 +316,19 @@
status.waiting = 0;
mypool.get_status( flags, status );
}
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+ static void set_create_cb (fn_dl_create *cb) {fn_create_cb =cb;}
+ static void set_destroy_cb (fn_dl_destroy *cb) {fn_destroy_cb =cb;}
+ static void set_pre_alloc_cb (fn_dl_pre_alloc *cb) {fn_pre_alloc_cb =cb;}
+ static void set_post_alloc_cb (fn_dl_post_alloc *cb){fn_post_alloc_cb=cb;}
+ static void set_pre_realloc_cb (fn_dl_pre_realloc *cb)
+ {fn_pre_realloc_cb = cb;}
+ static void set_post_realloc_cb (fn_dl_post_realloc *cb)
+ {fn_post_realloc_cb = cb;}
+ static void set_pre_free_cb (fn_dl_pre_free *cb) {fn_pre_free_cb =cb;}
+ static void set_post_free_cb (fn_dl_post_free *cb) {fn_post_free_cb =cb;}
+#endif
};
#endif // ifndef __MALLOC_IMPL_WANTED
Index: include/dlmallocimpl.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/dlmallocimpl.hxx,v
retrieving revision 1.3
diff -u -r1.3 dlmallocimpl.hxx
--- include/dlmallocimpl.hxx 23 May 2002 23:08:43 -0000 1.3
+++ include/dlmallocimpl.hxx 2 Nov 2002 12:16:49 -0000
@@ -148,6 +148,10 @@
// Destructor
~Cyg_Mempool_dlmalloc_Implementation() {}
+ // given a block of allocated memory, returns the size of the block
+ cyg_int32
+ addr2size( cyg_uint8 *addr );
+
// get some memory, return NULL if none available
cyg_uint8 *
try_alloc( cyg_int32 /* size */ );
Index: include/memfixed.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/memfixed.hxx,v
retrieving revision 1.4
diff -u -r1.4 memfixed.hxx
--- include/memfixed.hxx 23 May 2002 23:08:43 -0000 1.4
+++ include/memfixed.hxx 2 Nov 2002 12:16:50 -0000
@@ -85,8 +85,36 @@
// TYPE DEFINITIONS
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+// memory callback functionality
+class Cyg_Mempool_Fixed;
+typedef void fn_fix_create
+ (Cyg_Mempool_Fixed *pool, cyg_uint8 const *base_ptr, cyg_int32 size,
+ cyg_int32 unitsize);
+typedef void fn_fix_destroy
+ (Cyg_Mempool_Fixed *pool, cyg_uint8 const *base_ptr, cyg_int32 size);
+typedef void fn_fix_pre_alloc
+ (Cyg_Mempool_Fixed *pool);
+typedef void fn_fix_post_alloc
+ (Cyg_Mempool_Fixed *pool, cyg_uint8 **mem_ptr);
+typedef void fn_fix_pre_free
+ (Cyg_Mempool_Fixed *pool, cyg_uint8 **mem_ptr);
+typedef void fn_fix_post_free
+ (Cyg_Mempool_Fixed *pool, cyg_uint8 *mem_ptr, cyg_int32 size);
+#endif
+
class Cyg_Mempool_Fixed
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+private:
+ static fn_fix_create *fn_create_cb;
+ static fn_fix_destroy *fn_destroy_cb;
+ static fn_fix_pre_alloc *fn_pre_alloc_cb;
+ static fn_fix_post_alloc *fn_post_alloc_cb;
+ static fn_fix_pre_free *fn_pre_free_cb;
+ static fn_fix_post_free *fn_post_free_cb;
+#endif
+
protected:
#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_THREADAWARE
Cyg_Mempolt2<Cyg_Mempool_Fixed_Implementation> mypool;
@@ -138,6 +166,15 @@
// defined in common.hxx
void get_status( cyg_mempool_status_flag_t /* flags */,
Cyg_Mempool_Status & /* status */ );
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+ static void set_create_cb (fn_fix_create *cb) {fn_create_cb =cb;}
+ static void set_destroy_cb (fn_fix_destroy *cb) {fn_destroy_cb =cb;}
+ static void set_pre_alloc_cb (fn_fix_pre_alloc *cb) {fn_pre_alloc_cb =cb;}
+ static void set_post_alloc_cb (fn_fix_post_alloc *cb){fn_post_alloc_cb=cb;}
+ static void set_pre_free_cb (fn_fix_pre_free *cb) {fn_pre_free_cb =cb;}
+ static void set_post_free_cb (fn_fix_post_free *cb) {fn_post_free_cb =cb;}
+#endif
CYGDBG_DEFINE_CHECK_THIS
};
Index: include/mempolt2.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mempolt2.hxx,v
retrieving revision 1.3
diff -u -r1.3 mempolt2.hxx
--- include/mempolt2.hxx 23 May 2002 23:08:43 -0000 1.3
+++ include/mempolt2.hxx 2 Nov 2002 12:16:50 -0000
@@ -90,6 +90,9 @@
cyg_int32 size,
CYG_ADDRWORD arg_thru ); // Constructor
~Cyg_Mempolt2(); // Destructor
+
+ // get the size of a previously allocated block (does not include overhead)
+ cyg_int32 addr2size( cyg_uint8 *addr );
// get some memory; wait if none available; return NULL if failed
// due to interrupt
Index: 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
--- include/mempolt2.inl 23 May 2002 23:08:43 -0000 1.3
+++ include/mempolt2.inl 2 Nov 2002 12:16:50 -0000
@@ -90,7 +90,19 @@
// Unlock the scheduler and maybe switch threads
Cyg_Scheduler::unlock();
}
-
+
+// -------------------------------------------------------------------------
+// get the size of a previously allocated block of memory - overhead
+template <class T>
+inline cyg_int32
+Cyg_Mempolt2<T>::addr2size( cyg_uint8 *addr )
+{
+ CYG_REPORT_FUNCTION();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ return pool.addr2size ( addr );
+}
+
// -------------------------------------------------------------------------
// get some memory; wait if none available
template <class T>
Index: include/memvar.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/memvar.hxx,v
retrieving revision 1.4
diff -u -r1.4 memvar.hxx
--- include/memvar.hxx 23 May 2002 23:08:43 -0000 1.4
+++ include/memvar.hxx 2 Nov 2002 12:16:50 -0000
@@ -90,8 +90,42 @@
// TYPE DEFINITIONS
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+// memory callback functionality
+class Cyg_Mempool_Variable;
+typedef void fn_var_create
+ (Cyg_Mempool_Variable *pool, const cyg_uint8 *base_ptr, cyg_int32 size);
+typedef void fn_var_destroy
+ (Cyg_Mempool_Variable *pool, const cyg_uint8 *base_ptr, cyg_int32 size);
+typedef void fn_var_pre_alloc
+ (Cyg_Mempool_Variable *pool, cyg_int32 *size);
+typedef void fn_var_post_alloc
+ (Cyg_Mempool_Variable *pool, cyg_uint8 **mem_ptr, cyg_int32 size);
+typedef void fn_var_pre_realloc
+ (Cyg_Mempool_Variable *pool, cyg_uint8 **mem_ptr, cyg_int32 *newsize,
+ cyg_int32 oldsize);
+typedef void fn_var_post_realloc
+ (Cyg_Mempool_Variable *pool, cyg_uint8 **mem_ptr, cyg_int32 size);
+typedef void fn_var_pre_free
+ (Cyg_Mempool_Variable *pool, cyg_uint8 **mem_ptr, cyg_int32 *psize);
+typedef void fn_var_post_free
+ (Cyg_Mempool_Variable *pool, cyg_uint8 *mem_ptr, cyg_int32 size);
+#endif
+
class Cyg_Mempool_Variable
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+private:
+ static fn_var_create *fn_create_cb;
+ static fn_var_destroy *fn_destroy_cb;
+ static fn_var_pre_alloc *fn_pre_alloc_cb;
+ static fn_var_post_alloc *fn_post_alloc_cb;
+ static fn_var_pre_realloc *fn_pre_realloc_cb;
+ static fn_var_post_realloc *fn_post_realloc_cb;
+ static fn_var_pre_free *fn_pre_free_cb;
+ static fn_var_post_free *fn_post_free_cb;
+#endif
+
protected:
#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_THREADAWARE
Cyg_Mempolt2<Cyg_Mempool_Variable_Implementation> mypool;
@@ -154,6 +188,19 @@
void
get_status( cyg_mempool_status_flag_t /* flags */,
Cyg_Mempool_Status & /* status */ );
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ static void set_create_cb (fn_var_create *cb) {fn_create_cb =cb;}
+ static void set_destroy_cb (fn_var_destroy *cb) {fn_destroy_cb =cb;}
+ static void set_pre_alloc_cb (fn_var_pre_alloc *cb) {fn_pre_alloc_cb =cb;}
+ static void set_post_alloc_cb (fn_var_post_alloc *cb){fn_post_alloc_cb=cb;}
+ static void set_pre_realloc_cb (fn_var_pre_realloc *cb)
+ {fn_pre_realloc_cb = cb;}
+ static void set_post_realloc_cb (fn_var_post_realloc *cb)
+ {fn_post_realloc_cb = cb;}
+ static void set_pre_free_cb (fn_var_pre_free *cb) {fn_pre_free_cb =cb;}
+ static void set_post_free_cb (fn_var_post_free *cb) {fn_post_free_cb =cb;}
+#endif
CYGDBG_DEFINE_CHECK_THIS
};
Index: include/mvarimpl.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/include/mvarimpl.hxx,v
retrieving revision 1.3
diff -u -r1.3 mvarimpl.hxx
--- include/mvarimpl.hxx 23 May 2002 23:08:44 -0000 1.3
+++ include/mvarimpl.hxx 2 Nov 2002 12:16:51 -0000
@@ -114,6 +114,10 @@
// Destructor
~Cyg_Mempool_Variable_Implementation();
+ // get the size in bytes of a previously allocated block of memory
+ cyg_int32
+ addr2size( cyg_uint8 *addr );
+
// get size bytes of memory
cyg_uint8 *
try_alloc( cyg_int32 /* size */ );
Index: 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
--- include/mvarimpl.inl 23 May 2002 23:08:44 -0000 1.5
+++ include/mvarimpl.inl 2 Nov 2002 12:16:51 -0000
@@ -99,6 +99,12 @@
return ((cyg_uint8 *)dq + sizeof(struct memdq));
}
+inline cyg_int32
+Cyg_Mempool_Variable_Implementation::addr2size( cyg_uint8 *addr )
+{
+ return addr2memdq (addr)->size - sizeof(struct memdq);
+}
+
// -------------------------------------------------------------------------
inline void
Index: src/dlmalloc.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/src/dlmalloc.cxx,v
retrieving revision 1.6
diff -u -r1.6 dlmalloc.cxx
--- src/dlmalloc.cxx 23 May 2002 23:08:44 -0000 1.6
+++ src/dlmalloc.cxx 2 Nov 2002 12:16:53 -0000
@@ -1032,6 +1032,25 @@
*/
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_DLMALLOC_CALLBACK
+// callbacks used for debugging memory leaks
+fn_dl_create *Cyg_Mempool_dlmalloc::fn_create_cb = NULL;
+fn_dl_destroy *Cyg_Mempool_dlmalloc::fn_destroy_cb = NULL;
+fn_dl_pre_alloc *Cyg_Mempool_dlmalloc::fn_pre_alloc_cb = NULL;
+fn_dl_post_alloc *Cyg_Mempool_dlmalloc::fn_post_alloc_cb = NULL;
+fn_dl_pre_realloc *Cyg_Mempool_dlmalloc::fn_pre_realloc_cb = NULL;
+fn_dl_post_realloc *Cyg_Mempool_dlmalloc::fn_post_realloc_cb = NULL;
+fn_dl_pre_free *Cyg_Mempool_dlmalloc::fn_pre_free_cb = NULL;
+fn_dl_post_free *Cyg_Mempool_dlmalloc::fn_post_free_cb = NULL;
+#endif
+
+cyg_int32
+Cyg_Mempool_dlmalloc_Implementation::addr2size( cyg_uint8 *addr )
+{
+ return chunksize(mem2chunk(addr)) - SIZE_SZ;
+}
+
+
cyg_uint8 *
Cyg_Mempool_dlmalloc_Implementation::try_alloc( cyg_int32 bytes )
{
Index: src/memfixed.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/src/memfixed.cxx,v
retrieving revision 1.3
diff -u -r1.3 memfixed.cxx
--- src/memfixed.cxx 23 May 2002 23:08:45 -0000 1.3
+++ src/memfixed.cxx 2 Nov 2002 12:16:53 -0000
@@ -99,6 +99,16 @@
}
#endif
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+// callbacks used for debugging memory leaks
+fn_fix_create *Cyg_Mempool_Fixed::fn_create_cb = NULL;
+fn_fix_destroy *Cyg_Mempool_Fixed::fn_destroy_cb = NULL;
+fn_fix_pre_alloc *Cyg_Mempool_Fixed::fn_pre_alloc_cb = NULL;
+fn_fix_post_alloc *Cyg_Mempool_Fixed::fn_post_alloc_cb = NULL;
+fn_fix_pre_free *Cyg_Mempool_Fixed::fn_pre_free_cb = NULL;
+fn_fix_post_free *Cyg_Mempool_Fixed::fn_post_free_cb = NULL;
+#endif
+
// -------------------------------------------------------------------------
// Constructor: gives the base and size of the arena in which memory is
// to be carved out, note that management structures are taken from the
@@ -109,11 +119,26 @@
CYG_ADDRWORD alloc_unit )
: mypool( base, size, alloc_unit )
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+ if ( fn_create_cb != NULL ) {
+ (*fn_create_cb) (this, base, size, alloc_unit);
+ }
+#endif
}
// Destructor
Cyg_Mempool_Fixed::~Cyg_Mempool_Fixed()
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+ if ( fn_destroy_cb != NULL ) {
+ Cyg_Mempool_Status status;
+ mypool.get_status (
+ CYG_MEMPOOL_STAT_ORIGBASE
+ | CYG_MEMPOOL_STAT_ORIGSIZE,
+ status );
+ (*fn_destroy_cb) (this, status.origbase, status.origsize);
+ }
+#endif
}
// -------------------------------------------------------------------------
@@ -122,7 +147,24 @@
cyg_uint8 *
Cyg_Mempool_Fixed::alloc()
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this);
+ }
+
+ pRet = mypool.alloc ( 0 );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet);
+ }
+
+ return pRet;
+#else
return mypool.alloc( 0 );
+#endif
}
# ifdef CYGFUN_KERNEL_THREADS_TIMER
@@ -130,7 +172,24 @@
cyg_uint8 *
Cyg_Mempool_Fixed::alloc(cyg_tick_count delay_timeout )
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this);
+ }
+
+ pRet = mypool.alloc( 0, delay_timeout );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet);
+ }
+
+ return pRet;
+#else
return mypool.alloc( 0, delay_timeout );
+#endif
}
# endif
#endif
@@ -139,14 +198,48 @@
cyg_uint8 *
Cyg_Mempool_Fixed::try_alloc()
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this);
+ }
+
+ pRet = mypool.try_alloc( 0 );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet);
+ }
+
+ return pRet;
+#else
return mypool.try_alloc( 0 );
+#endif
}
// free the memory back to the pool
cyg_bool
Cyg_Mempool_Fixed::free( cyg_uint8 *p )
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_CALLBACK
+ bool
+ bRet;
+
+ if ( fn_pre_free_cb != NULL ) {
+ (*fn_pre_free_cb) (this, &p);
+ }
+
+ bRet = mypool.free( p, 0 );
+
+ if ( fn_post_free_cb != NULL ) {
+ (*fn_post_free_cb) (this, p, 0);
+ }
+
+ return bRet;
+#else
return mypool.free( p, 0 );
+#endif
}
// supposedly resize existing allocation. This is defined in the
Index: src/memvar.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/services/memalloc/common/current/src/memvar.cxx,v
retrieving revision 1.3
diff -u -r1.3 memvar.cxx
--- src/memvar.cxx 23 May 2002 23:08:45 -0000 1.3
+++ src/memvar.cxx 2 Nov 2002 12:16:54 -0000
@@ -98,6 +98,18 @@
}
#endif
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+// callbacks used for debugging memory leaks
+fn_var_create *Cyg_Mempool_Variable::fn_create_cb = NULL;
+fn_var_destroy *Cyg_Mempool_Variable::fn_destroy_cb = NULL;
+fn_var_pre_alloc *Cyg_Mempool_Variable::fn_pre_alloc_cb = NULL;
+fn_var_post_alloc *Cyg_Mempool_Variable::fn_post_alloc_cb = NULL;
+fn_var_pre_realloc *Cyg_Mempool_Variable::fn_pre_realloc_cb = NULL;
+fn_var_post_realloc *Cyg_Mempool_Variable::fn_post_realloc_cb = NULL;
+fn_var_pre_free *Cyg_Mempool_Variable::fn_pre_free_cb = NULL;
+fn_var_post_free *Cyg_Mempool_Variable::fn_post_free_cb = NULL;
+#endif
+
// -------------------------------------------------------------------------
// Constructor: gives the base and size of the arena in which memory is
// to be carved out
@@ -107,11 +119,26 @@
cyg_int32 alignment)
: mypool( base, size, (CYG_ADDRWORD)alignment )
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ if ( fn_create_cb != NULL ) {
+ (*fn_create_cb) (this, base, size);
+ }
+#endif
}
// Destructor
Cyg_Mempool_Variable::~Cyg_Mempool_Variable()
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ if ( fn_destroy_cb != NULL ) {
+ Cyg_Mempool_Status status;
+ mypool.get_status (
+ CYG_MEMPOOL_STAT_ORIGBASE
+ | CYG_MEMPOOL_STAT_ORIGSIZE,
+ status );
+ (*fn_destroy_cb) (this, status.origbase, status.origsize);
+ }
+#endif
}
// -------------------------------------------------------------------------
@@ -120,7 +147,23 @@
cyg_uint8 *
Cyg_Mempool_Variable::alloc(cyg_int32 size)
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this, &size);
+ }
+ pRet = mypool.alloc( size );
+
+ if ( fn_post_alloc_cb != NULL) {
+ (*fn_post_alloc_cb) (this, &pRet, size);
+ }
+
+ return pRet;
+#else
return mypool.alloc( size );
+#endif
}
# ifdef CYGFUN_KERNEL_THREADS_TIMER
@@ -128,7 +171,24 @@
cyg_uint8 *
Cyg_Mempool_Variable::alloc(cyg_int32 size, cyg_tick_count delay_timeout)
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this, &size);
+ }
+
+ pRet = mypool.alloc( size , delay_timeout );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet, size);
+ }
+
+ return pRet;
+#else
return mypool.alloc( size , delay_timeout );
+#endif
}
# endif
#endif
@@ -137,7 +197,24 @@
cyg_uint8 *
Cyg_Mempool_Variable::try_alloc(cyg_int32 size)
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ cyg_uint8
+ *pRet;
+
+ if ( fn_pre_alloc_cb != NULL ) {
+ (*fn_pre_alloc_cb) (this, &size);
+ }
+
+ pRet = mypool.try_alloc( size );
+
+ if ( fn_post_alloc_cb != NULL ) {
+ (*fn_post_alloc_cb) (this, &pRet, size);
+ }
+
+ return pRet;
+#else
return mypool.try_alloc( size );
+#endif
}
// resize existing allocation, if oldsize is non-NULL, previous
@@ -154,14 +231,58 @@
Cyg_Mempool_Variable::resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
cyg_int32 *oldsize )
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ cyg_uint8
+ *pRet;
+ cyg_int32
+ originalsize;
+
+ // get the original size of the block of memory
+ originalsize = mypool.addr2size (alloc_ptr);
+
+ if ( fn_pre_realloc_cb != NULL ) {
+ (*fn_pre_realloc_cb) (this, &alloc_ptr, &newsize, originalsize);
+ }
+
+ pRet = mypool.resize_alloc( alloc_ptr, newsize, oldsize );
+
+ if ( fn_post_realloc_cb != NULL ) {
+ (*fn_post_realloc_cb) (this, &pRet, newsize);
+ }
+
+ return pRet;
+#else
return mypool.resize_alloc( alloc_ptr, newsize, oldsize );
+#endif
}
// free the memory back to the pool
cyg_bool
Cyg_Mempool_Variable::free( cyg_uint8 *p, cyg_int32 size )
{
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_CALLBACK
+ cyg_bool
+ bRet;
+
+ if (0 == size) {
+ // if the size wasn't given specifically get it from the pointer
+ size = mypool.addr2size (p);
+ }
+
+ if ( fn_pre_free_cb != NULL ) {
+ (*fn_pre_free_cb) (this, &p, &size);
+ }
+
+ bRet = mypool.free( p, size );
+
+ if ( fn_post_free_cb != NULL ) {
+ (*fn_post_free_cb) (this, p, size);
+ }
+
+ return bRet;
+#else
return mypool.free( p, size );
+#endif
}
// Get memory pool status
More information about the Ecos-patches
mailing list