source: rtems/cpukit/sapi/include/rtems/rbheap.h @ 5c51ba1

4.115
Last change on this file since 5c51ba1 was 5c51ba1, checked in by Sebastian Huber <sebastian.huber@…>, on 04/16/12 at 08:38:31

rbheap: API changes and documentation

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