memorypool.h (6361B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2007--2024 Daniel Pittman and Christian Grothoff 4 Copyright (C) 2016--2024 Evgeny Grin (Karlson2k) 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with this library; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 /** 22 * @file memorypool.h 23 * @brief memory pool; mostly used for efficient (de)allocation 24 * for each connection and bounding memory use for each 25 * request 26 * @author Christian Grothoff 27 * @author Karlson2k (Evgeny Grin) 28 */ 29 30 #ifndef MEMORYPOOL_H 31 #define MEMORYPOOL_H 32 33 #include "mhd_options.h" 34 #ifdef HAVE_STDDEF_H 35 #include <stddef.h> 36 #endif /* HAVE_STDDEF_H */ 37 #ifdef HAVE_STDBOOL_H 38 #include <stdbool.h> 39 #endif 40 41 /** 42 * Opaque handle for a memory pool. 43 * Pools are not reentrant and must not be used 44 * by multiple threads. 45 */ 46 struct MemoryPool; 47 48 /** 49 * Initialize values for memory pools 50 */ 51 void 52 MHD_init_mem_pools_ (void); 53 54 55 /** 56 * Create a memory pool. 57 * 58 * @param max maximum size of the pool 59 * @return NULL on error 60 */ 61 struct MemoryPool * 62 MHD_pool_create (size_t max); 63 64 65 /** 66 * Destroy a memory pool. 67 * 68 * @param pool memory pool to destroy 69 */ 70 void 71 MHD_pool_destroy (struct MemoryPool *pool); 72 73 74 /** 75 * Allocate size bytes from the pool. 76 * 77 * @param pool memory pool to use for the operation 78 * @param size number of bytes to allocate 79 * @param from_end allocate from end of pool (set to 'true'); 80 * use this for small, persistent allocations that 81 * will never be reallocated 82 * @return NULL if the pool cannot support size more 83 * bytes 84 */ 85 void * 86 MHD_pool_allocate (struct MemoryPool *pool, 87 size_t size, 88 bool from_end); 89 90 /** 91 * Checks whether allocated block is re-sizable in-place. 92 * If block is not re-sizable in-place, it still could be shrunk, but freed 93 * memory will not be re-used until reset of the pool. 94 * @param pool the memory pool to use 95 * @param block the pointer to the allocated block to check 96 * @param block_size the size of the allocated @a block 97 * @return true if block can be resized in-place in the optimal way, 98 * false otherwise 99 */ 100 bool 101 MHD_pool_is_resizable_inplace (struct MemoryPool *pool, 102 void *block, 103 size_t block_size); 104 105 /** 106 * Try to allocate @a size bytes memory area from the @a pool. 107 * 108 * If allocation fails, @a required_bytes is updated with size required to be 109 * freed in the @a pool from rellocatable area to allocate requested number 110 * of bytes. 111 * Allocated memory area is always not rellocatable ("from end"). 112 * 113 * @param pool memory pool to use for the operation 114 * @param size the size of memory in bytes to allocate 115 * @param[out] required_bytes the pointer to variable to be updated with 116 * the size of the required additional free 117 * memory area, set to 0 if function succeeds. 118 * Cannot be NULL. 119 * @return the pointer to allocated memory area if succeed, 120 * NULL if the pool doesn't have enough space, required_bytes is updated 121 * with amount of space needed to be freed in rellocatable area or 122 * set to SIZE_MAX if requested size is too large for the pool. 123 */ 124 void * 125 MHD_pool_try_alloc (struct MemoryPool *pool, 126 size_t size, 127 size_t *required_bytes); 128 129 130 /** 131 * Reallocate a block of memory obtained from the pool. 132 * This is particularly efficient when growing or 133 * shrinking the block that was last (re)allocated. 134 * If the given block is not the most recently 135 * (re)allocated block, the memory of the previous 136 * allocation may be not released until the pool is 137 * destroyed or reset. 138 * 139 * @param pool memory pool to use for the operation 140 * @param old the existing block 141 * @param old_size the size of the existing block 142 * @param new_size the new size of the block 143 * @return new address of the block, or 144 * NULL if the pool cannot support @a new_size 145 * bytes (old continues to be valid for @a old_size) 146 */ 147 void * 148 MHD_pool_reallocate (struct MemoryPool *pool, 149 void *old, 150 size_t old_size, 151 size_t new_size); 152 153 154 /** 155 * Check how much memory is left in the @a pool 156 * 157 * @param pool pool to check 158 * @return number of bytes still available in @a pool 159 */ 160 size_t 161 MHD_pool_get_free (struct MemoryPool *pool); 162 163 164 /** 165 * Deallocate a block of memory obtained from the pool. 166 * 167 * If the given block is not the most recently 168 * (re)allocated block, the memory of the this block 169 * allocation may be not released until the pool is 170 * destroyed or reset. 171 * 172 * @param pool memory pool to use for the operation 173 * @param block the allocated block, the NULL is tolerated 174 * @param block_size the size of the allocated block 175 */ 176 void 177 MHD_pool_deallocate (struct MemoryPool *pool, 178 void *block, 179 size_t block_size); 180 181 182 /** 183 * Clear all entries from the memory pool except 184 * for @a keep of the given @a copy_bytes. The pointer 185 * returned should be a buffer of @a new_size where 186 * the first @a copy_bytes are from @a keep. 187 * 188 * @param pool memory pool to use for the operation 189 * @param keep pointer to the entry to keep (maybe NULL) 190 * @param copy_bytes how many bytes need to be kept at this address 191 * @param new_size how many bytes should the allocation we return have? 192 * (should be larger or equal to @a copy_bytes) 193 * @return addr new address of @a keep (if it had to change) 194 */ 195 void * 196 MHD_pool_reset (struct MemoryPool *pool, 197 void *keep, 198 size_t copy_bytes, 199 size_t new_size); 200 201 #endif