summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/free.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libcsupport/src/free.c')
-rw-r--r--cpukit/libcsupport/src/free.c43
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
)