diff options
Diffstat (limited to 'cpukit/libcsupport/src/free.c')
-rw-r--r-- | cpukit/libcsupport/src/free.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/cpukit/libcsupport/src/free.c b/cpukit/libcsupport/src/free.c index f4542e0c72..9f7c577852 100644 --- a/cpukit/libcsupport/src/free.c +++ b/cpukit/libcsupport/src/free.c @@ -23,6 +23,49 @@ #include "malloc_p.h" #include <stdlib.h> +#include <rtems/chain.h> + +static RTEMS_CHAIN_DEFINE_EMPTY( _Malloc_GC_list ); + +RTEMS_INTERRUPT_LOCK_DEFINE( static, _Malloc_GC_lock, "Malloc GC" ) + +static void *_Malloc_Get_deferred_free( void ) +{ + rtems_interrupt_lock_context lock_context; + void *p; + + rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context ); + p = rtems_chain_get_unprotected( &_Malloc_GC_list ); + rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context ); + + return p; +} + +void _Malloc_Process_deferred_frees( void ) +{ + rtems_chain_node *to_be_freed; + + /* + * If some free's have been deferred, then do them now. + */ + while ( ( to_be_freed = _Malloc_Get_deferred_free() ) != NULL ) { + free( to_be_freed ); + } +} + +static void _Malloc_Deferred_free( void *p ) +{ + rtems_interrupt_lock_context lock_context; + rtems_chain_node *node; + + node = (rtems_chain_node *) p; + + rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context ); + rtems_chain_initialize_node( node ); + rtems_chain_append_unprotected( &_Malloc_GC_list, node ); + rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context ); +} + void free( void *ptr ) |