[PATCH 2/2] malloc: Make deferred free support optional

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Jul 23 12:21:34 UTC 2020


Only include the deferred free support if free() is actually used by the
application.

The free() implementation in RTEMS supports that allocated memory is
freed in interrupt context.  Since the heap is protected by a mutex, the
frees issued in interrupt context cannot immediately be freed to the
heap, instead they are placed on a deferred free list.  This list is
emptied by the core allocation function
rtems_heap_allocate_aligned_with_boundary().  This adds a dependency to
free() in rtems_heap_allocate_aligned_with_boundary(). In order to
better support applications which only allocate memory and never free
it, this dependency should be avoided.  Provide a weak default
implementation of _Malloc_Process_deferred_frees() for
rtems_heap_allocate_aligned_with_boundary().  In the free() module
provide the strong implementation.

Update #4032.
---
 cpukit/libcsupport/src/free.c            | 43 ++++++++++++++++++++++++
 cpukit/libcsupport/src/malloc_deferred.c | 40 ++--------------------
 cpukit/libcsupport/src/malloc_p.h        |  2 --
 3 files changed, 46 insertions(+), 39 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
 )
diff --git a/cpukit/libcsupport/src/malloc_deferred.c b/cpukit/libcsupport/src/malloc_deferred.c
index 62c231d2f8..f66dd54676 100644
--- a/cpukit/libcsupport/src/malloc_deferred.c
+++ b/cpukit/libcsupport/src/malloc_deferred.c
@@ -27,14 +27,9 @@
 
 #include "malloc_p.h"
 
-#include <rtems/chain.h>
 #include <rtems/score/sysstate.h>
 #include <rtems/score/threaddispatch.h>
 
-static RTEMS_CHAIN_DEFINE_EMPTY( _Malloc_GC_list );
-
-RTEMS_INTERRUPT_LOCK_DEFINE( static, _Malloc_GC_lock, "Malloc GC" )
-
 Malloc_System_state _Malloc_System_state( void )
 {
   System_state_Codes state = _System_state_Get();
@@ -52,28 +47,12 @@ Malloc_System_state _Malloc_System_state( void )
   }
 }
 
-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_WEAK void _Malloc_Process_deferred_frees( void )
 {
-  rtems_chain_node *to_be_freed;
-
   /*
-   *  If some free's have been deferred, then do them now.
+   * Do nothing by default.  If free() is used by the application, then a
+   * strong implementation of this function will be provided.
    */
-  while ( ( to_be_freed = _Malloc_Get_deferred_free() ) != NULL ) {
-    free( to_be_freed );
-  }
 }
 
 void *rtems_heap_allocate_aligned_with_boundary(
@@ -125,19 +104,6 @@ void *rtems_heap_allocate_aligned_with_boundary(
   return p;
 }
 
-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 *rtems_malloc( size_t size )
 {
   if ( size == 0 ) {
diff --git a/cpukit/libcsupport/src/malloc_p.h b/cpukit/libcsupport/src/malloc_p.h
index f3715a9966..cb26050ff1 100644
--- a/cpukit/libcsupport/src/malloc_p.h
+++ b/cpukit/libcsupport/src/malloc_p.h
@@ -25,8 +25,6 @@ typedef enum {
 
 Malloc_System_state _Malloc_System_state( void );
 
-void _Malloc_Deferred_free( void * );
-
 void _Malloc_Process_deferred_frees( void );
 
 #ifdef __cplusplus
-- 
2.26.2



More information about the devel mailing list