source: rtems/cpukit/sapi/include/rtems/rbheap.h @ 599d71f

5
Last change on this file since 599d71f was 60fe374, checked in by Sebastian Huber <sebastian.huber@…>, on 08/03/14 at 11:02:58

rbtree: Add and use RBTree_Compare_result

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