Changeset 7746b0de in rtems


Ignore:
Timestamp:
Apr 8, 2020, 8:28:47 AM (4 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
4444094d
Parents:
6f94a83
git-author:
Sebastian Huber <sebastian.huber@…> (04/08/20 08:28:47)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/24/20 05:14:02)
Message:

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.

Location:
cpukit/libcsupport/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libcsupport/src/free.c

    r6f94a83 r7746b0de  
    2424#include <stdlib.h>
    2525
     26#include <rtems/chain.h>
     27
     28static RTEMS_CHAIN_DEFINE_EMPTY( _Malloc_GC_list );
     29
     30RTEMS_INTERRUPT_LOCK_DEFINE( static, _Malloc_GC_lock, "Malloc GC" )
     31
     32static void *_Malloc_Get_deferred_free( void )
     33{
     34  rtems_interrupt_lock_context lock_context;
     35  void *p;
     36
     37  rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context );
     38  p = rtems_chain_get_unprotected( &_Malloc_GC_list );
     39  rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context );
     40
     41  return p;
     42}
     43
     44void _Malloc_Process_deferred_frees( void )
     45{
     46  rtems_chain_node *to_be_freed;
     47
     48  /*
     49   *  If some free's have been deferred, then do them now.
     50   */
     51  while ( ( to_be_freed = _Malloc_Get_deferred_free() ) != NULL ) {
     52    free( to_be_freed );
     53  }
     54}
     55
     56static void _Malloc_Deferred_free( void *p )
     57{
     58  rtems_interrupt_lock_context lock_context;
     59  rtems_chain_node *node;
     60
     61  node = (rtems_chain_node *) p;
     62
     63  rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context );
     64  rtems_chain_initialize_node( node );
     65  rtems_chain_append_unprotected( &_Malloc_GC_list, node );
     66  rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context );
     67}
     68
    2669void free(
    2770  void *ptr
  • cpukit/libcsupport/src/malloc_deferred.c

    r6f94a83 r7746b0de  
    2828#include "malloc_p.h"
    2929
    30 #include <rtems/chain.h>
    3130#include <rtems/score/sysstate.h>
    3231#include <rtems/score/threaddispatch.h>
    33 
    34 static RTEMS_CHAIN_DEFINE_EMPTY( _Malloc_GC_list );
    35 
    36 RTEMS_INTERRUPT_LOCK_DEFINE( static, _Malloc_GC_lock, "Malloc GC" )
    3732
    3833Malloc_System_state _Malloc_System_state( void )
     
    5348}
    5449
    55 static void *_Malloc_Get_deferred_free( void )
     50RTEMS_WEAK void _Malloc_Process_deferred_frees( void )
    5651{
    57   rtems_interrupt_lock_context lock_context;
    58   void *p;
    59 
    60   rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context );
    61   p = rtems_chain_get_unprotected( &_Malloc_GC_list );
    62   rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context );
    63 
    64   return p;
    65 }
    66 
    67 void _Malloc_Process_deferred_frees( void )
    68 {
    69   rtems_chain_node *to_be_freed;
    70 
    7152  /*
    72    *  If some free's have been deferred, then do them now.
     53   * Do nothing by default.  If free() is used by the application, then a
     54   * strong implementation of this function will be provided.
    7355   */
    74   while ( ( to_be_freed = _Malloc_Get_deferred_free() ) != NULL ) {
    75     free( to_be_freed );
    76   }
    7756}
    7857
     
    126105}
    127106
    128 void _Malloc_Deferred_free( void *p )
    129 {
    130   rtems_interrupt_lock_context lock_context;
    131   rtems_chain_node *node;
    132 
    133   node = (rtems_chain_node *) p;
    134 
    135   rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context );
    136   rtems_chain_initialize_node( node );
    137   rtems_chain_append_unprotected( &_Malloc_GC_list, node );
    138   rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context );
    139 }
    140 
    141107void *rtems_malloc( size_t size )
    142108{
  • cpukit/libcsupport/src/malloc_p.h

    r6f94a83 r7746b0de  
    2626Malloc_System_state _Malloc_System_state( void );
    2727
    28 void _Malloc_Deferred_free( void * );
    29 
    3028void _Malloc_Process_deferred_frees( void );
    3129
Note: See TracChangeset for help on using the changeset viewer.