summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/malloc_initialize.c
blob: 913daf1a27d8f63377ae493a49f2498055011a08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
 * @file
 *
 * @brief Malloc initialization implementation.
 */

/*
 *  COPYRIGHT (c) 1989-2007.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  $Id$
 */

#if HAVE_CONFIG_H
#include "config.h"
#endif

#include <rtems.h>
#include <rtems/malloc.h>
#include <rtems/score/wkspace.h>
#include "malloc_p.h"

/* FIXME: Dummy function */
#ifndef RTEMS_NEWLIB
void RTEMS_Malloc_Initialize(
  void *heap_begin,
  uintptr_t heap_size,
  size_t sbrk_amount
)
{
}
#else
rtems_malloc_statistics_t rtems_malloc_statistics;
extern bool rtems_unified_work_area;

void RTEMS_Malloc_Initialize(
  void *heap_begin,
  uintptr_t heap_size,
  size_t sbrk_amount
)
{
  #if defined(RTEMS_MALLOC_BOUNDARY_HELPERS)
    /*
     *  If configured, initialize the boundary support
     */
    if ( rtems_malloc_boundary_helpers != NULL ) {
      (*rtems_malloc_boundary_helpers->initialize)();
    }
  #endif

  /*
   *  If configured, initialize the statistics support
   */
  if ( rtems_malloc_statistics_helpers != NULL ) {
    (*rtems_malloc_statistics_helpers->initialize)();
  }

  /*
   *  Initialize the garbage collection list to start with nothing on it.
   */
  malloc_deferred_frees_initialize();

  /*
   *  Initialize the optional sbrk support for extending the heap
   */
  if ( rtems_malloc_sbrk_helpers != NULL ) {
    void *new_heap_begin = (*rtems_malloc_sbrk_helpers->initialize)(
      heap_begin,
      sbrk_amount
    );

    heap_size -= (uintptr_t) new_heap_begin - (uintptr_t) heap_begin;
    heap_begin = new_heap_begin;
  }

  /*
   *  If this system is configured to use the same heap for
   *  the RTEMS Workspace and C Program Heap, then we need to
   *  be very very careful about destroying the initialization
   *  that has already been done.
   */
    
  /*
   *  If the BSP is not clearing out the workspace, then it is most likely
   *  not clearing out the initial memory for the heap.  There is no
   *  standard supporting zeroing out the heap memory.  But much code
   *  with UNIX history seems to assume that memory malloc'ed during
   *  initialization (before any free's) is zero'ed.  This is true most
   *  of the time under UNIX because zero'ing memory when it is first
   *  given to a process eliminates the chance of a process seeing data
   *  left over from another process.  This would be a security violation.
   */

  if (
    !rtems_unified_work_area
      && rtems_configuration_get_do_zero_of_workspace()
  ) {
     memset( heap_begin, 0, heap_size );
  }

  /*
   *  Unfortunately we cannot use assert if this fails because if this
   *  has failed we do not have a heap and if we do not have a heap
   *  STDIO cannot work because there will be no buffers.
   */

  if ( !rtems_unified_work_area ) {
    uintptr_t status = _Protected_heap_Initialize( 
      RTEMS_Malloc_Heap,
      heap_begin,
      heap_size,
      CPU_HEAP_ALIGNMENT
    );
    if ( status == 0 ) {
      rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
    }
  }

  MSBUMP( space_available, _Protected_heap_Get_size(RTEMS_Malloc_Heap) );

  #if defined(RTEMS_HEAP_DEBUG)
    if ( _Protected_heap_Walk( RTEMS_Malloc_Heap, 0, false ) ) {
      printk( "Malloc heap not initialized correctly\n" );
      rtems_print_buffer( heap_begin, 32 );
      printk( "\n" );
      rtems_print_buffer( (heap_begin + heap_size) - 48, 48 );
      rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
    }
  #endif
}
#endif