summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-04-08 10:28:47 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-07-24 07:14:02 +0200
commit7746b0def9787e9806f80a28efbe4c64d2b9e561 (patch)
tree76968a44a951bb7359f8f33e8763c5b5106e4550 /cpukit/libcsupport
parentscore: Add RTEMS_WEAK (diff)
downloadrtems-7746b0def9787e9806f80a28efbe4c64d2b9e561.tar.bz2
malloc: Make deferred free support optional
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. Close #4032.
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r--cpukit/libcsupport/src/free.c43
-rw-r--r--cpukit/libcsupport/src/malloc_deferred.c40
-rw-r--r--cpukit/libcsupport/src/malloc_p.h2
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