UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2016 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file mempool.h 31 * 32 * Memory pool implementation. 33 * 34 * @author Mike Becker 35 * @author Olaf Wintermann 36 */ 37 38 #ifndef UCX_MEMPOOL_H 39 #define UCX_MEMPOOL_H 40 41 #include "ucx.h" 42 #include <stddef.h> 43 #include "allocator.h" 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 /** 50 * UCX mempool structure. 51 */ 52 typedef struct { 53 /** UcxAllocator based on this pool */ 54 UcxAllocator *allocator; 55 56 /** List of pointers to pooled memory. */ 57 void **data; 58 59 /** Count of pooled memory items. */ 60 size_t ndata; 61 62 /** Memory pool size. */ 63 size_t size; 64 } UcxMempool; 65 66 /** Shorthand for a new default memory pool with a capacity of 16 elements. */ 67 #define ucx_mempool_new_default() ucx_mempool_new(16) 68 69 70 /** 71 * Creates a memory pool with the specified initial size. 72 * 73 * As the created memory pool automatically grows in size by 16 elements, when 74 * trying to allocate memory on a full pool, it is recommended that you use 75 * a multiple of 16 for the initial size. 76 * 77 * @param n initial pool size (should be a multiple of 16) 78 * @return a pointer to the new memory pool 79 */ 80 UcxMempool *ucx_mempool_new(size_t n); 81 82 /** 83 * Resizes a memory pool. 84 * 85 * @param pool the pool to resize 86 * @param newcap the new capacity 87 * @return <code>EXIT_SUCCESS</code> on success or 88 * <code>EXIT_FAILURE</code> on failure 89 */ 90 int ucx_mempool_chcap(UcxMempool *pool, size_t newcap); 91 92 /** 93 * Changes the pool size to the next smallest multiple of 16. 94 * 95 * You may use this macro, to reduce the pool size after freeing 96 * many pooled memory items. 97 * 98 * @param pool the pool to clamp 99 * @return <code>EXIT_SUCCESS</code> on success or 100 * <code>EXIT_FAILURE</code> on failure 101 */ 102 #define ucx_mempool_clamp(pool) ucx_mempool_chcap(pool, \ 103 (pool->ndata & ~0xF)+0x10) 104 105 /** 106 * Allocates pooled memory. 107 * 108 * @param pool the memory pool 109 * @param n amount of memory to allocate 110 * @return a pointer to the allocated memory 111 * @see ucx_allocator_malloc() 112 */ 113 void *ucx_mempool_malloc(UcxMempool *pool, size_t n); 114 /** 115 * Allocates a pooled memory array. 116 * 117 * The content of the allocated memory is set to zero. 118 * 119 * @param pool the memory pool 120 * @param nelem amount of elements to allocate 121 * @param elsize amount of memory per element 122 * @return a pointer to the allocated memory 123 * @see ucx_allocator_calloc() 124 */ 125 void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize); 126 127 /** 128 * Reallocates pooled memory. 129 * 130 * If the memory to be reallocated is not contained by the specified pool, the 131 * behavior is undefined. 132 * 133 * @param pool the memory pool 134 * @param ptr a pointer to the memory that shall be reallocated 135 * @param n the new size of the memory 136 * @return a pointer to the new location of the memory 137 * @see ucx_allocator_realloc() 138 */ 139 void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n); 140 141 /** 142 * Frees pooled memory. 143 * 144 * Before freeing the memory, the specified destructor function (if any) 145 * is called. 146 * 147 * If you specify memory, that is not pooled by the specified memory pool, the 148 * behavior is undefined. 149 * 150 * @param pool the memory pool 151 * @param ptr a pointer to the memory that shall be freed 152 * @see ucx_mempool_set_destr() 153 */ 154 void ucx_mempool_free(UcxMempool *pool, void *ptr); 155 156 /** 157 * Destroys a memory pool. 158 * 159 * For each element the destructor function (if any) is called and the element 160 * is freed. 161 * 162 * Each of the registered destructor function that has no corresponding element 163 * within the pool (namely those registered by ucx_mempool_reg_destr) is 164 * called interleaving with the element destruction, but with guarantee to the 165 * order in which they were registered (FIFO order). 166 * 167 * 168 * @param pool the mempool to destroy 169 */ 170 void ucx_mempool_destroy(UcxMempool *pool); 171 172 /** 173 * Sets a destructor function for the specified memory. 174 * 175 * The destructor is automatically called when the memory is freed or the 176 * pool is destroyed. 177 * 178 * The only requirement for the specified memory is, that it <b>MUST</b> be 179 * pooled memory by a UcxMempool or an element-compatible mempool. The pointer 180 * to the destructor function is saved in a reserved area before the actual 181 * memory. 182 * 183 * @param ptr pooled memory 184 * @param func a pointer to the destructor function 185 * @see ucx_mempool_free() 186 * @see ucx_mempool_destroy() 187 */ 188 void ucx_mempool_set_destr(void *ptr, ucx_destructor func); 189 190 /** 191 * Registers a destructor function for the specified (non-pooled) memory. 192 * 193 * This is useful, if you have memory that has not been allocated by a mempool, 194 * but shall be managed by a mempool. 195 * 196 * This function creates an entry in the specified mempool and the memory will 197 * therefore (logically) convert to pooled memory. 198 * 199 * @param pool the memory pool 200 * @param ptr data the destructor is registered for 201 * @param destr a pointer to the destructor function 202 */ 203 void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr); 204 205 #ifdef __cplusplus 206 } 207 #endif 208 209 #endif /* UCX_MEMPOOL_H */ 210 211