source: rtems/cpukit/include/rtems/rbheap.h @ 3db9c820

Last change on this file since 3db9c820 was 3db9c820, checked in by Sebastian Huber <sebastian.huber@…>, on 11/28/20 at 10:16:28

sapi: Canonicalize @defgroup and @file comments

Adjust group identifier and names to be in line with a common pattern.
Use common phrases for the group and file brief descriptions.

Update #3706.

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