1 /* 2 * UCW Library -- Memory Pools 3 * 4 * (c) 1997--2005 Martin Mares <mj@ucw.cz> 5 * (c) 2007 Pavel Charvat <pchar@ucw.cz> 6 * (c) 2015, 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> 7 * 8 * This software may be freely distributed and used according to the terms 9 * of the GNU Lesser General Public License. 10 */ 11 12 #pragma once 13 14 #include <string.h> 15 #include <stdint.h> 16 17 #define CPU_STRUCT_ALIGN (sizeof(void*)) 18 19 /*** 20 * [[defs]] 21 * Definitions 22 * ----------- 23 ***/ 24 25 /** 26 * Memory pool state (see mp_push(), ...). 27 * You should use this one as an opaque handle only, the insides are internal. 28 **/ 29 struct mempool_state { 30 unsigned free[2]; 31 void *last[2]; 32 }; 33 34 /** 35 * Memory pool. 36 * You should use this one as an opaque handle only, the insides are internal. 37 **/ 38 struct mempool { 39 struct mempool_state state; 40 void *unused, *last_big; 41 unsigned chunk_size, threshold, idx; 42 }; 43 44 struct mempool_stats { /** Mempool statistics. See mp_stats(). **/ 45 uint64_t total_size; /** Real allocated size in bytes. */ 46 unsigned chain_count[3]; /** Number of allocated chunks in small/big/unused chains. */ 47 unsigned chain_size[3]; /** Size of allocated chunks in small/big/unused chains. */ 48 }; 49 50 /*** 51 * [[basic]] 52 * Basic manipulation 53 * ------------------ 54 ***/ 55 56 /** 57 * Initialize a given mempool structure. 58 * \p chunk_size must be in the interval `[1, UINT_MAX / 2]`. 59 * It will allocate memory by this large chunks and take 60 * memory to satisfy requests from them. 61 * 62 * Memory pools can be treated as <<trans:respools,resources>>, see <<trans:res_mempool()>>. 63 **/ 64 void mp_init(struct mempool *pool, unsigned chunk_size); 65 66 /** 67 * Allocate and initialize a new memory pool. 68 * See \ref mp_init() for \p chunk_size limitations. 69 * 70 * The new mempool structure is allocated on the new mempool. 71 * 72 * Memory pools can be treated as <<trans:respools,resources>>, see <<trans:res_mempool()>>. 73 **/ 74 struct mempool *mp_new(unsigned chunk_size); 75 76 /** 77 * Cleanup mempool initialized by mp_init or mp_new. 78 * Frees all the memory allocated by this mempool and, 79 * if created by \ref mp_new(), the \p pool itself. 80 **/ 81 void mp_delete(struct mempool *pool); 82 83 /** 84 * Frees all data on a memory pool, but leaves it working. 85 * It can keep some of the chunks allocated to serve 86 * further allocation requests. Leaves the \p pool alive, 87 * even if it was created with \ref mp_new(). 88 **/ 89 void mp_flush(struct mempool *pool); 90 91 /** 92 * Compute some statistics for debug purposes. 93 * See the definition of the <<struct_mempool_stats,mempool_stats structure>>. 94 **/ 95 void mp_stats(struct mempool *pool, struct mempool_stats *stats); 96 uint64_t mp_total_size(struct mempool *pool); /** How many bytes were allocated by the pool. **/ 97 98 /*** 99 * [[alloc]] 100 * Allocation routines 101 * ------------------- 102 ***/ 103 104 /** 105 * The function allocates new \p size bytes on a given memory pool. 106 * If the \p size is zero, the resulting pointer is undefined, 107 * but it may be safely reallocated or used as the parameter 108 * to other functions below. 109 * 110 * The resulting pointer is always aligned to a multiple of 111 * `CPU_STRUCT_ALIGN` bytes and this condition remains true also 112 * after future reallocations. 113 **/ 114 void *mp_alloc(struct mempool *pool, unsigned size); 115 116 /** 117 * The same as \ref mp_alloc(), but the result may be unaligned. 118 **/ 119 void *mp_alloc_noalign(struct mempool *pool, unsigned size); 120 121 /** 122 * The same as \ref mp_alloc(), but fills the newly allocated memory with zeroes. 123 **/ 124 void *mp_alloc_zero(struct mempool *pool, unsigned size); 125