source: rtems/cpukit/libcsupport/src/free.c @ 54ec0264

Last change on this file since 54ec0264 was 7746b0de, checked in by Sebastian Huber <sebastian.huber@…>, on 04/08/20 at 08:28:47

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.

  • Property mode set to 100644
File size: 1.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup libcsupport
5 *
6 * @brief calloc()
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2007.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#ifdef RTEMS_NEWLIB
23#include "malloc_p.h"
24#include <stdlib.h>
25
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
69void free(
70  void *ptr
71)
72{
73  if ( !ptr )
74    return;
75
76  /*
77   *  Do not attempt to free memory if in a critical section or ISR.
78   */
79  if ( _Malloc_System_state() != MALLOC_SYSTEM_STATE_NORMAL ) {
80      _Malloc_Deferred_free(ptr);
81      return;
82  }
83
84  if ( !_Protected_heap_Free( RTEMS_Malloc_Heap, ptr ) ) {
85    rtems_fatal( RTEMS_FATAL_SOURCE_INVALID_HEAP_FREE, (rtems_fatal_code) ptr );
86  }
87}
88#endif
Note: See TracBrowser for help on using the repository browser.