00001 /* mempool.h - a memory pool implementation 00002 * 00003 * cp_mempool is a memory pool for fixed allocation sizes. 00004 * 00005 * cp_shared_mempool is a collection of cp_mempool objects. cp_shared_mempool 00006 * allows sharing cp_mempool instances that serve the same allocation size. 00007 * Call cp_shared_mempool_register to request an allocation size and use the 00008 * returned cp_mempool. 00009 * 00010 * cp_shared_mempool may also be used for aribitrary sizes allocations, but 00011 * this does not necessarily improve performance. Tests on Open BSD show 00012 * significant gains, whereas tests on Linux show a performance degradation for 00013 * generic allocation operations. Using cp_shared_mempool to share cp_mempool 00014 * objects between cp_* data structures does not reduce performance. The test 00015 * results are not conclusive and performance characteristics may also be 00016 * application specific. For best results, benchmark performance for your 00017 * application in realistic deployment scenarios before deciding whether to use 00018 * cp_shared_mempool. 00019 * 00020 * After instantiating a cp_shared_mempool, you may set one of 00021 * CP_SHARED_MEMPOOL_TYPE_2 or CP_SHARED_MEMPOOL_TYPE_1. If TYPE_2 is set, 00022 * requests for unregistered allocation sizes will return the requested size 00023 * rounded up to the machine word size, after instantiating a cp_mempool 00024 * serving the requested size if none exists. This could potentially use up 00025 * large amounts of memory. If TYPE_1 is set, unregistered allocation sizes 00026 * are rounded up to the next bit. E.g. a request for 513 bytes will return a 00027 * chunk of 1024 bytes. This might also use up large amounts of memory. 00028 * 00029 * Both cp_mempool and cp_shared_mempool represent a trade off of memory for 00030 * speed and should not be used if memory is tight or if the total allocation 00031 * may exceed the amount of physical memory available to the program, so as to 00032 * prevent swapping. Note that even if using the provided cp_mempool_free or 00033 * cp_shared_mempool_free functions, the memory returned to the pool is kept 00034 * for future requests and is ultimately released back to the general "malloc" 00035 * library only when the memory pool is destroyed. 00036 * 00037 * AUTHOR: Kyle Wheeler, Ilan Aelion 00038 */ 00039 #ifndef _CP_MEMPOOL_H 00040 #define _CP_MEMPOOL_H 00041 00042 #include "common.h" 00043 #include "collection.h" 00044 00045 __BEGIN_DECLS 00046 00047 struct _cp_mempool; 00048 00049 typedef void (*cp_mempool_callback_fn)(void *prm, 00050 struct _cp_mempool *pool, 00051 void *mem); 00052 00053 typedef struct _cp_mempool 00054 { 00055 size_t item_size; 00056 size_t alloc_size; 00057 size_t items_per_alloc; 00058 00059 char *reuse_pool; 00060 char *alloc_pool; 00061 size_t alloc_pool_pos; 00062 00063 int refcount; 00064 00065 cp_mempool_callback_fn alloc_callback; 00066 void *callback_prm; 00067 00068 int mode; 00069 cp_mutex *lock; 00070 #if !defined(CP_HAS_PTHREAD_MUTEX_RECURSIVE) && !defined(CP_HAS_PTHREAD_MUTEX_RECURSIVE_NP) 00071 cp_thread txowner; 00072 int txowner_in; 00073 #endif /* CP_HAS_PTHREAD_MUTEX_RECURSIVE */ 00074 } cp_mempool; 00075 00076 #define cp_mempool_item_size(p) ((p)->item_size) 00077 00078 /* cp_mempool_create_by_option */ 00079 CPROPS_DLL 00080 cp_mempool *cp_mempool_create_by_option(const int mode, 00081 size_t chunksize, 00082 size_t multiple); 00083 00084 /* cp_mempool_create_by_option */ 00085 CPROPS_DLL 00086 cp_mempool *cp_mempool_create(const size_t chunksize); 00087 00088 /* increment refcount */ 00089 CPROPS_DLL 00090 int cp_mempool_inc_refcount(cp_mempool *pool); 00091 00092 /* cp_mempool_alloc */ 00093 CPROPS_DLL 00094 void *cp_mempool_alloc(cp_mempool * const pool); 00095 00096 /* cp_mempool_calloc */ 00097 CPROPS_DLL 00098 void *cp_mempool_calloc(cp_mempool * const pool); 00099 00100 /* cp_mempool_free */ 00101 CPROPS_DLL 00102 int cp_mempool_free(cp_mempool * const pool, void *data); 00103 00104 /* cp_mempool_destroy */ 00105 CPROPS_DLL 00106 void cp_mempool_destroy(cp_mempool *pool); 00107 00108 #include "rb.h" 00109 #include "hashtable.h" 00110 00111 typedef struct _shared_mempool_entry 00112 { 00113 size_t item_size; 00114 cp_mempool *pool; 00115 struct _shared_mempool_entry *next; 00116 } shared_mempool_entry; 00117 00118 /* cp_shared_mempool is a generalized memory pool. It allows requesting variable 00119 * block sizes. For best results, register the required block sizes in advance. 00120 * requests for unregistered block sizes will return memory from a default 00121 * internal list, which rounds up the block size to the next bit. For example 00122 * allocating an unregisterd block of size 12 will return a 16 byte block. 00123 * In partcular large allocations could return a lot of extra memory. 00124 */ 00125 typedef CPROPS_DLL struct _cp_shared_mempool 00126 { 00127 unsigned int reg_tbl_size; 00128 unsigned int reg_tbl_count; 00129 00130 shared_mempool_entry **reg_tbl; 00131 struct _cp_rbtree *chunk_tracker; 00132 00133 int mode; 00134 int gm_mode; 00135 00136 /* lock for mempool lists */ 00137 cp_mutex *lock; 00138 00139 int multiple; /* number of pages to allocate in sub pools */ 00140 } cp_shared_mempool; 00141 00142 /* ``smaller'': arbitrary size allocations are rounded up to the next bit. The 00143 * pool is ``smaller'' in that up to about WORD_SIZE internal memory pools are 00144 * allocated to serve unregistered allocation size requests. 00145 */ 00146 #define CP_SHARED_MEMPOOL_TYPE_1 1 00147 /* ``faster'': arbitrary size allocations are rounded up to the word size. The 00148 * pool is ``faster'' in that typically the allocation overhead is smaller, and 00149 * the number of operations required to determine which pool to use internally 00150 * is smaller. On the other hand, since a large number of memory pool could be 00151 * allocated internally, this may not be usable in some circumstances. 00152 */ 00153 #define CP_SHARED_MEMPOOL_TYPE_2 2 00154 00155 /* cp_shared_mempool_create */ 00156 CPROPS_DLL 00157 cp_shared_mempool *cp_shared_mempool_create(); 00158 00159 /* cp_shared_mempool_create_by_option */ 00160 CPROPS_DLL 00161 cp_shared_mempool * 00162 cp_shared_mempool_create_by_option(int mode, 00163 int arbitrary_allocation_strategy, 00164 int size_hint, 00165 int page_count); 00166 00167 /* cp_shared_mempool destroy */ 00168 CPROPS_DLL 00169 void cp_shared_mempool_destroy(cp_shared_mempool *pool); 00170 00171 /* cp_shared_mempool_register */ 00172 CPROPS_DLL 00173 cp_mempool *cp_shared_mempool_register(cp_shared_mempool *pool, size_t size); 00174 00175 /* cp_shared_mempool_alloc */ 00176 CPROPS_DLL 00177 void *cp_shared_mempool_alloc(cp_shared_mempool *pool, size_t size); 00178 00179 /* cp_shared_mempool_calloc */ 00180 CPROPS_DLL 00181 void *cp_shared_mempool_calloc(cp_shared_mempool *pool, size_t size); 00182 00183 /* cp_shared_mempool_free */ 00184 CPROPS_DLL 00185 void cp_shared_mempool_free(cp_shared_mempool *pool, void *p); 00186 00187 __END_DECLS 00188 00189 #endif /* _CP_MEMPOOL_H */ 00190