summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/include/rtems/malloc.h
blob: 25a2e4ea50185cb698ca3f0a02c142c23b68d71e (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/**
 * @file rtems/malloc.h
 *
 * This file defines the interface to RTEMS extensions to the Malloc Family.
 */

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

#ifndef _RTEMS_MALLOC_H
#define _RTEMS_MALLOC_H

#include <rtems.h>
#include <rtems/bspIo.h>
#include <rtems/libcsupport.h> /* for malloc_walk() */

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 *  @defgroup MallocSupport Malloc Support
 *
 *  @ingroup libcsupport
 *
 *  @brief RTEMS extensions to the Malloc Family
 */

/**
 *  @brief C program heap control.
 *
 *  This is the pointer to the heap control structure used to manage the C
 *  program heap.
 */
extern Heap_Control *RTEMS_Malloc_Heap;

void RTEMS_Malloc_Initialize(
  const Heap_Area *areas,
  size_t area_count,
  Heap_Initialization_or_extend_handler extend
);

/*
 *  Malloc Statistics Structure
 */
typedef struct {
    uint32_t    space_available;             /* current size of malloc area */
    uint32_t    malloc_calls;                /* # calls to malloc */
    uint32_t    memalign_calls;              /* # calls to memalign */
    uint32_t    free_calls;
    uint32_t    realloc_calls;
    uint32_t    calloc_calls;
    uint32_t    max_depth;		     /* most ever malloc'd at 1 time */
    uintmax_t   lifetime_allocated;
    uintmax_t   lifetime_freed;
} rtems_malloc_statistics_t;

/*
 *  Malloc statistics plugin
 */
typedef struct {
  void (*initialize)(void);
  void (*at_malloc)(void *);
  void (*at_free)(void *);
} rtems_malloc_statistics_functions_t;

extern rtems_malloc_statistics_functions_t
  rtems_malloc_statistics_helpers_table;
extern rtems_malloc_statistics_functions_t *rtems_malloc_statistics_helpers;

extern ptrdiff_t RTEMS_Malloc_Sbrk_amount;

static inline void rtems_heap_set_sbrk_amount( ptrdiff_t sbrk_amount )
{
  RTEMS_Malloc_Sbrk_amount = sbrk_amount;
}

typedef void *(*rtems_heap_extend_handler)(
  Heap_Control *heap,
  size_t alloc_size
);

/**
 *  @brief RTEMS Extend Heap via Sbrk
 */
void *rtems_heap_extend_via_sbrk(
  Heap_Control *heap,
  size_t alloc_size
);

void *rtems_heap_null_extend(
  Heap_Control *heap,
  size_t alloc_size
);

extern const rtems_heap_extend_handler rtems_malloc_extend_handler;

/*
 * Malloc Plugin to Dirty Memory at Allocation Time
 */
typedef void (*rtems_malloc_dirtier_t)(void *, size_t);
extern rtems_malloc_dirtier_t rtems_malloc_dirty_helper;

/**
 *  @brief Dirty Memory Function
 *
 *  This method fills the specified area with a non-zero pattern
 *  to aid in debugging programs which do not initialize their
 *  memory allocated from the heap.
 */
void rtems_malloc_dirty_memory(
  void   *start,
  size_t  size
);

/**
 *  @brief Print Malloc Statistic Usage Report
 *
 *  This method fills in the called provided malloc statistics area.
 *
 *  @return This method returns 0 if successful and -1 on error.
 */
int malloc_get_statistics(
  rtems_malloc_statistics_t *stats
);

/**
 *  @brief Print Malloc Statistic Usage Report
 *
 *  This method prints a malloc statistics report.
 *
 *  @note It uses printk to print the report.
 */
void malloc_report_statistics(void);

/**
 *  @brief Print Malloc Statistic Usage Report
 *
 *  This method prints a malloc statistics report.
 *
 *  @param[in] context is the context to pass to the print handler
 *  @param[in] print is the print handler
 *
 *  @note It uses the CALLER's routine to print the report.
 */
void malloc_report_statistics_with_plugin(
  void                  *context,
  rtems_printk_plugin_t  print
);

/**
 *  @brief RTEMS Variation on Aligned Memory Allocation
 *
 *  This method is a help memalign implementation which does all
 *  error checking done by posix_memalign() EXCEPT it does NOT
 *  place numeric restrictions on the alignment value.
 *
 *  @param[in] pointer points to the user pointer
 *  @param[in] alignment is the desired alignment
 *  @param[in] size is the allocation request size in bytes
 *
 *  @return This methods returns zero on success and a POSIX errno
 *          value to indicate the failure condition.  On success
 *          *pointer will contain the address of the allocated memory.
 */
int rtems_memalign(
  void   **pointer,
  size_t   alignment,
  size_t   size
);

/**
 * @brief Allocates a memory area of size @a size bytes from the heap.
 *
 * If the alignment parameter @a alignment is not equal to zero, the allocated
 * memory area will begin at an address aligned by this value.
 *
 * If the boundary parameter @a boundary is not equal to zero, the allocated
 * memory area will comply with a boundary constraint.  The boundary value
 * specifies the set of addresses which are aligned by the boundary value.  The
 * interior of the allocated memory area will not contain an element of this
 * set.  The begin or end address of the area may be a member of the set.
 *
 * A size value of zero will return a unique address which may be freed with
 * free().
 *
 * The memory allocated by this function can be released with a call to free().
 *
 * @return A pointer to the begin of the allocated memory area, or @c NULL if
 * no memory is available or the parameters are inconsistent.
 */
void *rtems_heap_allocate_aligned_with_boundary(
  size_t size,
  uintptr_t alignment,
  uintptr_t boundary
);

/**
 * @brief Extends the memory available for the heap using the memory area
 * starting at @a area_begin of size @a area_size bytes.
 *
 * There are no alignment requirements.  The memory area must be big enough to
 * contain some maintenance blocks.  It must not overlap parts of the current
 * heap areas.  Disconnected subordinate heap areas will lead to used blocks
 * which cover the gaps.  Extending with an inappropriate memory area will
 * corrupt the heap.
 *
 * @retval RTEMS_SUCCESSFUL Successful operation.
 * @retval RTEMS_INVALID_ADDRESS Invalid memory area.
 */
rtems_status_code rtems_heap_extend(
  void *area_begin,
  uintptr_t area_size
);

/**
 * @brief Greedy allocate that empties the heap.
 *
 * Afterwards the heap has at most @a block_count allocatable blocks of sizes
 * specified by @a block_sizes.  The @a block_sizes must point to an array with
 * @a block_count members.  All other blocks are used.
 *
 * @see rtems_heap_greedy_free().
 */
void *rtems_heap_greedy_allocate(
  const uintptr_t *block_sizes,
  size_t block_count
);

/**
 * @brief Greedy allocate all blocks except the largest free block.
 *
 * Afterwards the heap has at most one allocatable block.  This block is the
 * largest free block if it exists.  The allocatable size of this block is
 * stored in @a allocatable_size.  All other blocks are used.
 *
 * @see rtems_heap_greedy_free().
 */
void *rtems_heap_greedy_allocate_all_except_largest(
  uintptr_t *allocatable_size
);

/**
 * @brief Frees space of a greedy allocation.
 *
 * The @a opaque argument must be the return value of
 * rtems_heap_greedy_allocate() or
 * rtems_heap_greedy_allocate_all_except_largest().
 */
void rtems_heap_greedy_free( void *opaque );

#ifdef __cplusplus
}
#endif

#endif