![]() |
|
|||
File indexing completed on 2025-05-11 08:24:13
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSAPIRBHeap 0007 * 0008 * @brief This header file provides the Red-Black Tree Heap API. 0009 */ 0010 0011 /* 0012 * Copyright (c) 2012 embedded brains GmbH & Co. KG 0013 * 0014 * Redistribution and use in source and binary forms, with or without 0015 * modification, are permitted provided that the following conditions 0016 * are met: 0017 * 1. Redistributions of source code must retain the above copyright 0018 * notice, this list of conditions and the following disclaimer. 0019 * 2. Redistributions in binary form must reproduce the above copyright 0020 * notice, this list of conditions and the following disclaimer in the 0021 * documentation and/or other materials provided with the distribution. 0022 * 0023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0024 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0025 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0026 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0027 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0028 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0029 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0030 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0031 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0033 * POSSIBILITY OF SUCH DAMAGE. 0034 */ 0035 0036 #ifndef _RTEMS_RBHEAP_H 0037 #define _RTEMS_RBHEAP_H 0038 0039 #include <rtems.h> 0040 #include <rtems/chain.h> 0041 #include <rtems/rbtree.h> 0042 0043 #ifdef __cplusplus 0044 extern "C" { 0045 #endif 0046 0047 /** 0048 * @defgroup RTEMSAPIRBHeap Red-Black Tree Heap 0049 * 0050 * @ingroup RTEMSAPI 0051 * 0052 * @brief The red-black tree heap provides a memory allocator using a red-black 0053 * tree to maintain blocks of memory. 0054 * 0055 * The red-black tree heap provides a memory allocator suitable to implement 0056 * the malloc() and free() interface. It uses a first-fit allocation strategy. 0057 * In the red-black tree heap the administration data structures are not 0058 * contained in the managed memory area. Thus writing beyond the boundaries of 0059 * a chunk does not damage the data to maintain the heap. This can be used for 0060 * example in a task stack allocator which protects the task stacks from access 0061 * by other tasks. The allocated and free memory parts of the managed area are 0062 * called chunks. Each chunk needs a descriptor which is stored outside of the 0063 * managed area. 0064 */ 0065 /**@{*/ 0066 0067 /** 0068 * @brief Red-black heap chunk descriptor. 0069 */ 0070 typedef struct { 0071 /** 0072 * This chain node can be used in two chains 0073 * - the chain of spare chunk descriptors and 0074 * - the chain of free chunks in the managed memory area. 0075 * 0076 * In case this chain node is not part of a chain, the chunk represents a 0077 * used chunk in the managed memory area. 0078 */ 0079 rtems_chain_node chain_node; 0080 0081 /** 0082 * Tree node for chunks that represent a part of the managed memory area. 0083 * These chunks are either free or used. 0084 */ 0085 rtems_rbtree_node tree_node; 0086 0087 /** 0088 * Begin address of the chunk. The address alignment it specified in the 0089 * @ref rtems_rbheap_control. 0090 */ 0091 uintptr_t begin; 0092 0093 /** 0094 * Size of the chunk in bytes. 0095 */ 0096 uintptr_t size; 0097 } rtems_rbheap_chunk; 0098 0099 typedef struct rtems_rbheap_control rtems_rbheap_control; 0100 0101 /** 0102 * @brief Handler to extend the available chunk descriptors. 0103 * 0104 * This handler is called when no more chunk descriptors are available. An 0105 * example implementation is this: 0106 * 0107 * @code 0108 * void extend_descriptors_with_malloc(rtems_rbheap_control *control) 0109 * { 0110 * rtems_rbheap_chunk *chunk = malloc(sizeof(*chunk)); 0111 * 0112 * if (chunk != NULL) { 0113 * rtems_rbheap_add_to_spare_descriptor_chain(control, chunk); 0114 * } 0115 * } 0116 * @endcode 0117 * 0118 * @see rtems_rbheap_extend_descriptors_never() and 0119 * rtems_rbheap_extend_descriptors_with_malloc(). 0120 */ 0121 typedef void (*rtems_rbheap_extend_descriptors)(rtems_rbheap_control *control); 0122 0123 /** 0124 * @brief Red-black heap control. 0125 */ 0126 struct rtems_rbheap_control { 0127 /** 0128 * Chain of free chunks in the managed memory area. 0129 */ 0130 rtems_chain_control free_chunk_chain; 0131 0132 /** 0133 * Chain of free chunk descriptors. Descriptors are consumed during 0134 * allocation and may be produced during free if contiguous chunks can be 0135 * coalesced. In case of descriptor starvation the @ref extend_descriptors 0136 * handler will be called. 0137 */ 0138 rtems_chain_control spare_descriptor_chain; 0139 0140 /** 0141 * Tree of chunks representing the state of the managed memory area. 0142 */ 0143 rtems_rbtree_control chunk_tree; 0144 0145 /** 0146 * Minimum chunk begin alignment in bytes. 0147 */ 0148 uintptr_t alignment; 0149 0150 /** 0151 * Handler to extend the available chunk descriptors. 0152 */ 0153 rtems_rbheap_extend_descriptors extend_descriptors; 0154 0155 /** 0156 * User specified argument handler for private handler data. 0157 */ 0158 void *handler_arg; 0159 }; 0160 0161 /** 0162 * @brief Initializes the red-black tree heap @a control. 0163 * 0164 * @param[in, out] control The red-black tree heap. 0165 * @param[in] area_begin The managed memory area begin. 0166 * @param[in] area_size The managed memory area size. 0167 * @param[in] alignment The minimum chunk alignment. 0168 * @param[in] extend_descriptors The handler to extend the available chunk 0169 * descriptors. 0170 * @param[in] handler_arg The handler argument. 0171 * 0172 * @retval RTEMS_SUCCESSFUL Successful operation. 0173 * @retval RTEMS_INVALID_ADDRESS The memory area is invalid. 0174 * @retval RTEMS_NO_MEMORY Not enough chunk descriptors. 0175 */ 0176 rtems_status_code rtems_rbheap_initialize( 0177 rtems_rbheap_control *control, 0178 void *area_begin, 0179 uintptr_t area_size, 0180 uintptr_t alignment, 0181 rtems_rbheap_extend_descriptors extend_descriptors, 0182 void *handler_arg 0183 ); 0184 0185 /** 0186 * @brief Allocates a chunk of memory of at least @a size bytes from the 0187 * red-black tree heap @a control. 0188 * 0189 * The chunk begin is aligned by the value specified in 0190 * rtems_rbheap_initialize(). 0191 * 0192 * @param[in, out] control The red-black tree heap. 0193 * @param[in] size The requested chunk size in bytes. 0194 * 0195 * @retval NULL Not enough free space in the heap. 0196 * @retval otherwise Pointer to allocated chunk of memory. 0197 */ 0198 void *rtems_rbheap_allocate(rtems_rbheap_control *control, size_t size); 0199 0200 /** 0201 * @brief Frees a chunk of memory @a ptr allocated from the red-black tree heap 0202 * @a control. 0203 * 0204 * @param[in, out] control The red-black tree heap. 0205 * @param[in] ptr The pointer to the chunk of memory. 0206 * 0207 * @retval RTEMS_SUCCESSFUL Successful operation. 0208 * @retval RTEMS_INVALID_ID The chunk of memory is not a valid chunk in the 0209 * red-black tree heap. 0210 * @retval RTEMS_INCORRECT_STATE The chunk of memory is not in the right state. 0211 */ 0212 rtems_status_code rtems_rbheap_free(rtems_rbheap_control *control, void *ptr); 0213 0214 static inline rtems_chain_control *rtems_rbheap_get_spare_descriptor_chain( 0215 rtems_rbheap_control *control 0216 ) 0217 { 0218 return &control->spare_descriptor_chain; 0219 } 0220 0221 static inline void rtems_rbheap_add_to_spare_descriptor_chain( 0222 rtems_rbheap_control *control, 0223 rtems_rbheap_chunk *chunk 0224 ) 0225 { 0226 rtems_chain_control *chain = 0227 rtems_rbheap_get_spare_descriptor_chain(control); 0228 0229 rtems_chain_initialize_node(&chunk->chain_node); 0230 rtems_chain_prepend_unprotected(chain, &chunk->chain_node); 0231 } 0232 0233 static inline void rtems_rbheap_set_extend_descriptors( 0234 rtems_rbheap_control *control, 0235 rtems_rbheap_extend_descriptors extend_descriptors 0236 ) 0237 { 0238 control->extend_descriptors = extend_descriptors; 0239 } 0240 0241 static inline void *rtems_rbheap_get_handler_arg( 0242 const rtems_rbheap_control *control 0243 ) 0244 { 0245 return control->handler_arg; 0246 } 0247 0248 static inline void rtems_rbheap_set_handler_arg( 0249 rtems_rbheap_control *control, 0250 void *handler_arg 0251 ) 0252 { 0253 control->handler_arg = handler_arg; 0254 } 0255 0256 /** 0257 * @brief Chunk descriptor extend handler that does nothing. 0258 */ 0259 void rtems_rbheap_extend_descriptors_never(rtems_rbheap_control *control); 0260 0261 /** 0262 * @brief Chunk descriptor extend handler that uses malloc(). 0263 */ 0264 void rtems_rbheap_extend_descriptors_with_malloc( 0265 rtems_rbheap_control *control 0266 ); 0267 0268 /** @} */ 0269 0270 /* Private API */ 0271 0272 #define rtems_rbheap_chunk_of_node(node) \ 0273 RTEMS_CONTAINER_OF(node, rtems_rbheap_chunk, tree_node) 0274 0275 static inline bool rtems_rbheap_is_chunk_free(const rtems_rbheap_chunk *chunk) 0276 { 0277 return !rtems_chain_is_node_off_chain(&chunk->chain_node); 0278 } 0279 0280 #ifdef __cplusplus 0281 } 0282 #endif 0283 0284 #endif /* _RTEMS_RBHEAP_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |