universe@103: /* universe@103: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. olaf@13: * universe@259: * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. universe@103: * universe@103: * Redistribution and use in source and binary forms, with or without universe@103: * modification, are permitted provided that the following conditions are met: universe@103: * universe@103: * 1. Redistributions of source code must retain the above copyright universe@103: * notice, this list of conditions and the following disclaimer. universe@103: * universe@103: * 2. Redistributions in binary form must reproduce the above copyright universe@103: * notice, this list of conditions and the following disclaimer in the universe@103: * documentation and/or other materials provided with the distribution. universe@103: * universe@103: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@103: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@103: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@103: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@103: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@103: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@103: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@103: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@103: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@103: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@103: * POSSIBILITY OF SUCH DAMAGE. olaf@13: */ olaf@13: universe@135: /** universe@135: * @file mempool.h universe@135: * universe@135: * Memory pool implementation. universe@135: * universe@135: * @author Mike Becker universe@135: * @author Olaf Wintermann universe@135: */ universe@135: olaf@120: #ifndef UCX_MEMPOOL_H olaf@120: #define UCX_MEMPOOL_H olaf@13: universe@259: #include "ucx.h" universe@259: #include "allocator.h" universe@38: #include universe@38: olaf@13: #ifdef __cplusplus olaf@13: extern "C" { olaf@13: #endif olaf@13: universe@135: /** universe@135: * UCX mempool structure. universe@135: */ olaf@13: typedef struct { olaf@158: /** UcxAllocator based on this pool */ olaf@158: UcxAllocator *allocator; olaf@158: universe@135: /** List of pointers to pooled memory. */ olaf@158: void **data; universe@146: universe@135: /** Count of pooled memory items. */ olaf@158: size_t ndata; universe@146: universe@135: /** Memory pool size. */ olaf@158: size_t size; olaf@13: } UcxMempool; olaf@13: universe@135: /** Shorthand for a new default memory pool with a capacity of 16 elements. */ universe@135: #define ucx_mempool_new_default() ucx_mempool_new(16) universe@48: universe@135: universe@135: /** universe@135: * Creates a memory pool with the specified initial size. universe@135: * universe@241: * As the created memory pool automatically grows in size by factor two when universe@135: * trying to allocate memory on a full pool, it is recommended that you use universe@241: * a power of two for the initial size. universe@135: * universe@241: * @param n initial pool size (should be a power of two, e.g. 16) universe@135: * @return a pointer to the new memory pool universe@241: * @see ucx_mempool_new_default() universe@135: */ olaf@13: UcxMempool *ucx_mempool_new(size_t n); universe@135: universe@135: /** universe@135: * Resizes a memory pool. universe@135: * universe@241: * This function will fail if the new capacity is not sufficient for the universe@241: * present data. universe@241: * universe@135: * @param pool the pool to resize universe@135: * @param newcap the new capacity universe@241: * @return zero on success or non-zero on failure universe@135: */ universe@15: int ucx_mempool_chcap(UcxMempool *pool, size_t newcap); olaf@13: universe@135: /** universe@135: * Allocates pooled memory. universe@135: * universe@135: * @param pool the memory pool universe@135: * @param n amount of memory to allocate universe@135: * @return a pointer to the allocated memory universe@135: * @see ucx_allocator_malloc() universe@135: */ olaf@13: void *ucx_mempool_malloc(UcxMempool *pool, size_t n); universe@135: /** universe@135: * Allocates a pooled memory array. universe@135: * universe@181: * The content of the allocated memory is set to zero. universe@135: * universe@135: * @param pool the memory pool universe@135: * @param nelem amount of elements to allocate universe@135: * @param elsize amount of memory per element universe@135: * @return a pointer to the allocated memory universe@135: * @see ucx_allocator_calloc() universe@135: */ olaf@13: void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize); universe@146: universe@135: /** universe@135: * Reallocates pooled memory. universe@135: * universe@215: * If the memory to be reallocated is not contained by the specified pool, the universe@215: * behavior is undefined. universe@141: * universe@135: * @param pool the memory pool universe@135: * @param ptr a pointer to the memory that shall be reallocated universe@135: * @param n the new size of the memory universe@181: * @return a pointer to the new location of the memory universe@135: * @see ucx_allocator_realloc() universe@135: */ olaf@13: void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n); universe@146: universe@135: /** universe@135: * Frees pooled memory. universe@135: * universe@135: * Before freeing the memory, the specified destructor function (if any) universe@135: * is called. universe@135: * universe@215: * If you specify memory, that is not pooled by the specified memory pool, the universe@241: * program will terminate with a call to abort(). universe@135: * universe@135: * @param pool the memory pool universe@135: * @param ptr a pointer to the memory that shall be freed universe@135: * @see ucx_mempool_set_destr() universe@135: */ olaf@113: void ucx_mempool_free(UcxMempool *pool, void *ptr); olaf@13: universe@135: /** universe@135: * Destroys a memory pool. universe@135: * universe@135: * For each element the destructor function (if any) is called and the element universe@135: * is freed. universe@135: * universe@135: * Each of the registered destructor function that has no corresponding element universe@135: * within the pool (namely those registered by ucx_mempool_reg_destr) is universe@135: * called interleaving with the element destruction, but with guarantee to the universe@135: * order in which they were registered (FIFO order). universe@135: * universe@135: * universe@135: * @param pool the mempool to destroy universe@135: */ olaf@113: void ucx_mempool_destroy(UcxMempool *pool); olaf@13: universe@135: /** universe@135: * Sets a destructor function for the specified memory. universe@135: * universe@135: * The destructor is automatically called when the memory is freed or the universe@135: * pool is destroyed. universe@135: * universe@135: * The only requirement for the specified memory is, that it MUST be universe@225: * pooled memory by a UcxMempool or an element-compatible mempool. The pointer universe@135: * to the destructor function is saved in a reserved area before the actual universe@135: * memory. universe@135: * universe@135: * @param ptr pooled memory universe@135: * @param func a pointer to the destructor function universe@135: * @see ucx_mempool_free() universe@135: * @see ucx_mempool_destroy() universe@135: */ olaf@13: void ucx_mempool_set_destr(void *ptr, ucx_destructor func); universe@135: universe@135: /** universe@135: * Registers a destructor function for the specified (non-pooled) memory. universe@135: * universe@135: * This is useful, if you have memory that has not been allocated by a mempool, universe@135: * but shall be managed by a mempool. universe@135: * universe@135: * This function creates an entry in the specified mempool and the memory will universe@135: * therefore (logically) convert to pooled memory. universe@135: * universe@135: * @param pool the memory pool universe@135: * @param ptr data the destructor is registered for universe@135: * @param destr a pointer to the destructor function universe@135: */ olaf@13: void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr); olaf@13: olaf@13: #ifdef __cplusplus olaf@13: } olaf@13: #endif olaf@13: olaf@120: #endif /* UCX_MEMPOOL_H */ olaf@13: