source: rtems/cpukit/sapi/include/rtems/rbheap.h @ 27f071cd

4.115
Last change on this file since 27f071cd was 27f071cd, checked in by Alex Ivanov <alexivanov97@…>, on 01/08/13 at 13:13:41

sapi: Doxygen Clean Up Task #1

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