source: rtems/cpukit/include/rtems/rbheap.h @ 255fe43

Last change on this file since 255fe43 was 255fe43, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 20:40:44

cpukit/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSAPIRBHeap
5 *
6 * @brief This header file provides the Red-Black Tree Heap API.
7 */
8
9/*
10 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#ifndef _RTEMS_RBHEAP_H
18#define _RTEMS_RBHEAP_H
19
20#include <rtems.h>
21#include <rtems/chain.h>
22#include <rtems/rbtree.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/**
29 * @defgroup RTEMSAPIRBHeap Red-Black Tree Heap
30 *
31 * @ingroup RTEMSAPI
32 *
33 * @brief The red-black tree heap provides a memory allocator using a red-black
34 *   tree to maintain blocks of memory.
35 *
36 * The red-black tree heap provides a memory allocator suitable to implement
37 * the malloc() and free() interface.  It uses a first-fit allocation strategy.
38 * In the red-black tree heap the administration data structures are not
39 * contained in the managed memory area.  Thus writing beyond the boundaries of
40 * a chunk does not damage the data to maintain the heap.  This can be used for
41 * example in a task stack allocator which protects the task stacks from access
42 * by other tasks.  The allocated and free memory parts of the managed area are
43 * called chunks.  Each chunk needs a descriptor which is stored outside of the
44 * managed area.
45 */
46/**@{*/
47
48/**
49 * @brief Red-black heap chunk descriptor.
50 */
51typedef struct {
52  /**
53   * This chain node can be used in two chains
54   *  - the chain of spare chunk descriptors and
55   *  - the chain of free chunks in the managed memory area.
56   *
57   * In case this chain node is not part of a chain, the chunk represents a
58   * used chunk in the managed memory area.
59   */
60  rtems_chain_node chain_node;
61
62  /**
63   * Tree node for chunks that represent a part of the managed memory area.
64   * These chunks are either free or used.
65   */
66  rtems_rbtree_node tree_node;
67
68  /**
69   * Begin address of the chunk.  The address alignment it specified in the
70   * @ref rtems_rbheap_control.
71   */
72  uintptr_t begin;
73
74  /**
75   * Size of the chunk in bytes.
76   */
77  uintptr_t size;
78} rtems_rbheap_chunk;
79
80typedef struct rtems_rbheap_control rtems_rbheap_control;
81
82/**
83 * @brief Handler to extend the available chunk descriptors.
84 *
85 * This handler is called when no more chunk descriptors are available.  An
86 * example implementation is this:
87 *
88 * @code
89 * void extend_descriptors_with_malloc(rtems_rbheap_control *control)
90 * {
91 *   rtems_rbheap_chunk *chunk = malloc(sizeof(*chunk));
92 *
93 *   if (chunk != NULL) {
94 *     rtems_rbheap_add_to_spare_descriptor_chain(control, chunk);
95 *   }
96 * }
97 * @endcode
98 *
99 * @see rtems_rbheap_extend_descriptors_never() and
100 * rtems_rbheap_extend_descriptors_with_malloc().
101 */
102typedef void (*rtems_rbheap_extend_descriptors)(rtems_rbheap_control *control);
103
104/**
105 * @brief Red-black heap control.
106 */
107struct rtems_rbheap_control {
108  /**
109   * Chain of free chunks in the managed memory area.
110   */
111  rtems_chain_control free_chunk_chain;
112
113  /**
114   * Chain of free chunk descriptors.  Descriptors are consumed during
115   * allocation and may be produced during free if contiguous chunks can be
116   * coalesced.  In case of descriptor starvation the @ref extend_descriptors
117   * handler will be called.
118   */
119  rtems_chain_control spare_descriptor_chain;
120
121  /**
122   * Tree of chunks representing the state of the managed memory area.
123   */
124  rtems_rbtree_control chunk_tree;
125
126  /**
127   * Minimum chunk begin alignment in bytes.
128   */
129  uintptr_t alignment;
130
131  /**
132   * Handler to extend the available chunk descriptors.
133   */
134  rtems_rbheap_extend_descriptors extend_descriptors;
135
136  /**
137   * User specified argument handler for private handler data.
138   */
139  void *handler_arg;
140};
141
142/**
143 * @brief Initializes the red-black tree heap @a control.
144 *
145 * @param[in, out] control The red-black tree heap.
146 * @param[in] area_begin The managed memory area begin.
147 * @param[in] area_size The managed memory area size.
148 * @param[in] alignment The minimum chunk alignment.
149 * @param[in] extend_descriptors The handler to extend the available chunk
150 * descriptors.
151 * @param[in] handler_arg The handler argument.
152 *
153 * @retval RTEMS_SUCCESSFUL Successful operation.
154 * @retval RTEMS_INVALID_ADDRESS The memory area is invalid.
155 * @retval RTEMS_NO_MEMORY Not enough chunk descriptors.
156 */
157rtems_status_code rtems_rbheap_initialize(
158  rtems_rbheap_control *control,
159  void *area_begin,
160  uintptr_t area_size,
161  uintptr_t alignment,
162  rtems_rbheap_extend_descriptors extend_descriptors,
163  void *handler_arg
164);
165
166/**
167 * @brief Allocates a chunk of memory of at least @a size bytes from the
168 * red-black tree heap @a control.
169 *
170 * The chunk begin is aligned by the value specified in
171 * rtems_rbheap_initialize().
172 *
173 * @param[in, out] control The red-black tree heap.
174 * @param[in] size The requested chunk size in bytes.
175 *
176 * @retval NULL Not enough free space in the heap.
177 * @retval otherwise Pointer to allocated chunk of memory.
178 */
179void *rtems_rbheap_allocate(rtems_rbheap_control *control, size_t size);
180
181/**
182 * @brief Frees a chunk of memory @a ptr allocated from the red-black tree heap
183 * @a control.
184 *
185 * @param[in, out] control The red-black tree heap.
186 * @param[in] ptr The pointer to the chunk of memory.
187 *
188 * @retval RTEMS_SUCCESSFUL Successful operation.
189 * @retval RTEMS_INVALID_ID The chunk of memory is not a valid chunk in the
190 * red-black tree heap.
191 * @retval RTEMS_INCORRECT_STATE The chunk of memory is not in the right state.
192 */
193rtems_status_code rtems_rbheap_free(rtems_rbheap_control *control, void *ptr);
194
195static inline rtems_chain_control *rtems_rbheap_get_spare_descriptor_chain(
196  rtems_rbheap_control *control
197)
198{
199  return &control->spare_descriptor_chain;
200}
201
202static inline void rtems_rbheap_add_to_spare_descriptor_chain(
203  rtems_rbheap_control *control,
204  rtems_rbheap_chunk *chunk
205)
206{
207  rtems_chain_control *chain =
208    rtems_rbheap_get_spare_descriptor_chain(control);
209
210  rtems_chain_initialize_node(&chunk->chain_node);
211  rtems_chain_prepend_unprotected(chain, &chunk->chain_node);
212}
213
214static inline void rtems_rbheap_set_extend_descriptors(
215  rtems_rbheap_control *control,
216  rtems_rbheap_extend_descriptors extend_descriptors
217)
218{
219  control->extend_descriptors = extend_descriptors;
220}
221
222static inline void *rtems_rbheap_get_handler_arg(
223  const rtems_rbheap_control *control
224)
225{
226  return control->handler_arg;
227}
228
229static inline void rtems_rbheap_set_handler_arg(
230  rtems_rbheap_control *control,
231  void *handler_arg
232)
233{
234  control->handler_arg = handler_arg;
235}
236
237/**
238 * @brief Chunk descriptor extend handler that does nothing.
239 */
240void rtems_rbheap_extend_descriptors_never(rtems_rbheap_control *control);
241
242/**
243 * @brief Chunk descriptor extend handler that uses malloc().
244 */
245void rtems_rbheap_extend_descriptors_with_malloc(
246  rtems_rbheap_control *control
247);
248
249/** @} */
250
251/* Private API */
252
253#define rtems_rbheap_chunk_of_node(node) \
254  RTEMS_CONTAINER_OF(node, rtems_rbheap_chunk, tree_node)
255
256static inline bool rtems_rbheap_is_chunk_free(const rtems_rbheap_chunk *chunk)
257{
258  return !rtems_chain_is_node_off_chain(&chunk->chain_node);
259}
260
261#ifdef __cplusplus
262}
263#endif
264
265#endif /* _RTEMS_RBHEAP_H */
Note: See TracBrowser for help on using the repository browser.