src/cx/mempool.h

changeset 1323
deccdb82f24e
parent 1283
89935fea4b7c
child 1325
20caf6efaf07
equal deleted inserted replaced
1322:7be10b57f658 1323:deccdb82f24e
41 41
42 #ifdef __cplusplus 42 #ifdef __cplusplus
43 extern "C" { 43 extern "C" {
44 #endif 44 #endif
45 45
46 /** Internal structure for pooled memory. */ 46 struct cx_mempool_memory_s {
47 struct cx_mempool_memory_s; 47 /** The destructor. */
48 cx_destructor_func destructor;
49 /** The actual memory. */
50 char c[];
51 };
52
53 struct cx_mempool_memory2_s {
54 /** The destructor. */
55 cx_destructor_func2 destructor;
56 /** Data for the destructor. */
57 void *data;
58 /** The actual memory. */
59 char c[];
60 };
61
62 struct cx_mempool_foreign_memory_s {
63 /** The foreign memory. */
64 void* mem;
65 union {
66 /** Simple destructor. */
67 cx_destructor_func destr;
68 /** Advanced destructor. */
69 cx_destructor_func2 destr2;
70 };
71 /** Data for the advanced destructor. */
72 void *destr2_data;
73 };
74
75 /** Specifies how individual blocks are allocated. */
76 enum cx_mempool_type {
77 /**
78 * Allows registration of cx_destructor_func for each memory block.
79 */
80 CX_MEMPOOL_TYPE_SIMPLE,
81 /**
82 * Allows registration of cx_destructor_func2 for each memory block.
83 */
84 CX_MEMPOOL_TYPE_ADVANCED,
85 /**
86 * No individual destructor registration allowed.
87 *
88 * In this mode, no additional memory per block is allocated.
89 */
90 CX_MEMPOOL_TYPE_PURE,
91 };
48 92
49 /** 93 /**
50 * The basic structure of a memory pool. 94 * The basic structure of a memory pool.
51 * Should be the first member of an actual memory pool implementation. 95 * Should be the first member of an actual memory pool implementation.
52 */ 96 */
53 struct cx_mempool_s { 97 struct cx_mempool_s {
54 /** The provided allocator. */ 98 /** The provided allocator. */
55 const CxAllocator *allocator; 99 const CxAllocator *allocator;
56 100
57 /**
58 * A destructor that shall be automatically registered for newly allocated memory.
59 * This destructor MUST NOT free the memory.
60 */
61 cx_destructor_func auto_destr;
62
63 /** Array of pooled memory. */ 101 /** Array of pooled memory. */
64 struct cx_mempool_memory_s **data; 102 void **data;
65 103
66 /** Number of pooled memory items. */ 104 /** Number of pooled memory items. */
67 size_t size; 105 size_t size;
68 106
69 /** Memory pool capacity. */ 107 /** Memory pool capacity. */
70 size_t capacity; 108 size_t capacity;
109
110 /** Array of registered memory. */
111 struct cx_mempool_foreign_memory_s *registered;
112
113 /** Number of registered memory items. */
114 size_t registered_size;
115
116 /** Capacity for registered memory. */
117 size_t registered_capacity;
118
119 /**
120 * A destructor that shall be called before deallocating a memory block.
121 * This destructor MUST NOT free the memory itself.
122 *
123 * It is guaranteed that this destructor is called after the individual
124 * destructor of the memory block and before @c destr2.
125 */
126 cx_destructor_func destr;
127
128 /**
129 * A destructor that shall be called before deallocating a memory block.
130 * This destructor MUST NOT free the memory itself.
131 *
132 * It is guaranteed that this destructor is called after the individual
133 * destructor of the memory block and @c destr.
134 */
135 cx_destructor_func2 destr2;
136
137 /**
138 * Additional data for the @c destr2.
139 */
140 void *destr2_data;
71 }; 141 };
72 142
73 /** 143 /**
74 * Common type for all memory pool implementations. 144 * Common type for all memory pool implementations.
75 */ 145 */
82 */ 152 */
83 cx_attr_export 153 cx_attr_export
84 void cxMempoolFree(CxMempool *pool); 154 void cxMempoolFree(CxMempool *pool);
85 155
86 /** 156 /**
87 * Creates an array-based memory pool with a shared destructor function. 157 * Creates an array-based memory pool.
88 * 158 *
89 * This destructor MUST NOT free the memory. 159 * The type determines how much additional memory is allocated per block
90 * 160 * to register a destructor function.
91 * @param capacity the initial capacity of the pool 161 *
92 * @param destr optional destructor function to use for allocated memory 162 * @param capacity the initial capacity of the pool (an implementation default if zero)
163 * @param type the type of memory pool
93 * @return the created memory pool or @c NULL if allocation failed 164 * @return the created memory pool or @c NULL if allocation failed
94 */ 165 */
95 cx_attr_nodiscard 166 cx_attr_nodiscard
96 cx_attr_malloc 167 cx_attr_malloc
97 cx_attr_dealloc(cxMempoolFree, 1) 168 cx_attr_dealloc(cxMempoolFree, 1)
98 cx_attr_export 169 cx_attr_export
99 CxMempool *cxMempoolCreate(size_t capacity, cx_destructor_func destr); 170 CxMempool *cxMempoolCreate(size_t capacity, enum cx_mempool_type type);
171
172 /**
173 * Sets the global destructor for all memory blocks within the specified pool.
174 *
175 * @param pool (@c CxMempool*) the memory pool
176 * @param fnc (@c cx_destructor_func) the destructor that shall be applied to all memory blocks
177 */
178 #define cxMempoolGlobalDestructor(pool, fnc) \
179 (pool)->destr = (cx_destructor_func)(fnc)
180
181 /**
182 * Sets the global destructor for all memory blocks within the specified pool.
183 *
184 * @param pool (@c CxMempool*) the memory pool
185 * @param fnc (@c cx_destructor_func2) the destructor that shall be applied to all memory blocks
186 * @param data (@c void*) additional data for the destructor function
187 */
188 #define cxMempoolGlobalDestructor2(pool, fnc, data) \
189 (pool)->destr2 = (cx_destructor_func2)(fnc); (pool)->destr2_data = (data)
100 190
101 /** 191 /**
102 * Creates a basic array-based memory pool. 192 * Creates a basic array-based memory pool.
103 * 193 *
104 * @param capacity (@c size_t) the initial capacity of the pool 194 * @param capacity (@c size_t) the initial capacity of the pool
105 * @return (@c CxMempool*) the created memory pool or @c NULL if allocation failed 195 * @return (@c CxMempool*) the created memory pool or @c NULL if allocation failed
106 */ 196 */
107 #define cxMempoolCreateSimple(capacity) cxMempoolCreate(capacity, NULL) 197 #define cxMempoolCreateSimple(capacity) cxMempoolCreate(capacity, CX_MEMPOOL_TYPE_SIMPLE)
108 198
109 /** 199 /**
110 * Sets the destructor function for a specific allocated memory object. 200 * Sets the destructor function for a specific allocated memory object.
111 * 201 *
202 * If the type of memory pool is not #CX_MEMPOOL_TYPE_SIMPLE, the behavior is undefined.
112 * If the memory is not managed by a UCX memory pool, the behavior is undefined. 203 * If the memory is not managed by a UCX memory pool, the behavior is undefined.
113 * The destructor MUST NOT free the memory. 204 * The destructor MUST NOT free the memory.
114 * 205 *
115 * @param memory the object allocated in the pool 206 * @param memory the object allocated in the pool
116 * @param fnc the destructor function 207 * @param fnc the destructor function
121 void *memory, 212 void *memory,
122 cx_destructor_func fnc 213 cx_destructor_func fnc
123 ); 214 );
124 215
125 /** 216 /**
126 * Removes the destructor function for a specific allocated memory object. 217 * Sets the destructor function for a specific allocated memory object.
127 * 218 *
219 * If the type of memory pool is not #CX_MEMPOOL_TYPE_ADVANCED, the behavior is undefined.
128 * If the memory is not managed by a UCX memory pool, the behavior is undefined. 220 * If the memory is not managed by a UCX memory pool, the behavior is undefined.
129 * The destructor MUST NOT free the memory. 221 * The destructor MUST NOT free the memory.
130 * 222 *
131 * @param memory the object allocated in the pool 223 * @param memory the object allocated in the pool
224 * @param fnc the destructor function
225 * @param data additional data for the destructor function
226 */
227 cx_attr_nonnull
228 cx_attr_export
229 void cxMempoolSetDestructor2(
230 void *memory,
231 cx_destructor_func2 fnc,
232 void *data
233 );
234
235 /**
236 * Removes the destructor function for a specific allocated memory object.
237 *
238 * If the type of memory pool is not #CX_MEMPOOL_TYPE_SIMPLE, the behavior is undefined.
239 * If the memory is not managed by a UCX memory pool, the behavior is undefined.
240 *
241 * @param memory the object allocated in the pool
132 */ 242 */
133 cx_attr_nonnull 243 cx_attr_nonnull
134 cx_attr_export 244 cx_attr_export
135 void cxMempoolRemoveDestructor(void *memory); 245 void cxMempoolRemoveDestructor(void *memory);
136 246
137 /** 247 /**
248 * Removes the destructor function for a specific allocated memory object.
249 *
250 * If the type of memory pool is not #CX_MEMPOOL_TYPE_ADVANCED, the behavior is undefined.
251 * If the memory is not managed by a UCX memory pool, the behavior is undefined.
252 *
253 * @param memory the object allocated in the pool
254 */
255 cx_attr_nonnull
256 cx_attr_export
257 void cxMempoolRemoveDestructor2(void *memory);
258
259 /**
138 * Registers foreign memory with this pool. 260 * Registers foreign memory with this pool.
139 * 261 *
140 * The destructor, in contrast to memory allocated by the pool, MUST free the memory. 262 * The destructor, in contrast to memory allocated by the pool, MUST free the memory.
141 * 263 * This function can be used with any pool of any type, since destructors for registered memory
142 * A small portion of memory will be allocated to register the information in the pool. 264 * are entirely independent of the pool's memory management.
143 * If that allocation fails, this function will return non-zero. 265 *
266 * The destructor for the registered memory will be called after all pooled items have been freed.
144 * 267 *
145 * @param pool the pool 268 * @param pool the pool
146 * @param memory the object to register (MUST NOT be already allocated in the pool) 269 * @param memory the object to register (MUST NOT be already allocated in the pool)
147 * @param destr the destructor function 270 * @param destr the destructor function
148 * @retval zero success 271 * @retval zero success
154 CxMempool *pool, 277 CxMempool *pool,
155 void *memory, 278 void *memory,
156 cx_destructor_func destr 279 cx_destructor_func destr
157 ); 280 );
158 281
282
283 /**
284 * Registers foreign memory with this pool.
285 *
286 * The destructor, in contrast to memory allocated by the pool, MUST free the memory.
287 * This function can be used with any pool of any type, since destructors for registered memory
288 * are entirely independent of the pool's memory management.
289 *
290 * The destructor for the registered memory will be called after all pooled items have been freed.
291 *
292 * @attention The data pointer MUST NOT be @c NULL.
293 * If you wish to register a destructor without additional data, use cxMempoolRegister().
294 *
295 * @param pool the pool
296 * @param memory the object to register (MUST NOT be already allocated in the pool)
297 * @param destr the destructor function
298 * @param data additional data for the destructor function
299 * @retval zero success
300 * @retval non-zero failure
301 */
302 cx_attr_nonnull
303 cx_attr_export
304 int cxMempoolRegister2(
305 CxMempool *pool,
306 void *memory,
307 cx_destructor_func2 destr,
308 void *data
309 );
310
159 /** 311 /**
160 * Transfers all the memory managed by one pool to another. 312 * Transfers all the memory managed by one pool to another.
161 * 313 *
162 * The allocator of the source pool will also be transferred and registered with the destination pool 314 * The allocator of the source pool will also be transferred and registered with the destination pool
163 * and stays valid, as long as the destination pool is not destroyed. 315 * and stays valid, as long as the destination pool is not destroyed.
164 * 316 *
165 * The source pool will get a completely new allocator and can be reused or destroyed afterward. 317 * The source pool will get a completely new allocator and can be reused or destroyed afterward.
318 *
319 * This function fails when the destination pool has a different type than the source pool.
166 * 320 *
167 * @param source the pool to move the memory from 321 * @param source the pool to move the memory from
168 * @param dest the pool where to transfer the memory to 322 * @param dest the pool where to transfer the memory to
169 * @retval zero success 323 * @retval zero success
170 * @retval non-zero failure 324 * @retval non-zero allocation failure or incompatible pools
171 */ 325 */
172 cx_attr_nonnull 326 cx_attr_nonnull
173 cx_attr_export 327 cx_attr_export
174 int cxMempoolTransfer( 328 int cxMempoolTransfer(
175 CxMempool *source, 329 CxMempool *source,
177 ); 331 );
178 332
179 /** 333 /**
180 * Transfers an object from one pool to another. 334 * Transfers an object from one pool to another.
181 * 335 *
182 * You can only transfer objects that have been allocated by this pool. 336 * This function fails when the destination pool has a different type than the source pool.
183 * Objects that have been registered with cxMempoolRegister() cannot be transferred this way.
184 * 337 *
185 * @attention If the object maintains a reference to the pool's allocator, 338 * @attention If the object maintains a reference to the pool's allocator,
186 * you must make sure to update that reference to the allocator of the destination pool. 339 * you must make sure to update that reference to the allocator of the destination pool.
187 * 340 *
188 * @param source the pool to move the memory from 341 * @param source the pool to move the memory from
189 * @param dest the pool where to transfer the memory to 342 * @param dest the pool where to transfer the memory to
190 * @param obj pointer to the object that shall be transferred 343 * @param obj pointer to the object that shall be transferred
191 * @retval zero success 344 * @retval zero success
192 * @retval non-zero failure or object was not found in the source pool 345 * @retval non-zero failure, or the object was not found in the source pool, or the pools are incompatible
193 */ 346 */
194 cx_attr_nonnull 347 cx_attr_nonnull
195 cx_attr_export 348 cx_attr_export
196 int cxMempoolTransferObject( 349 int cxMempoolTransferObject(
197 CxMempool *source, 350 CxMempool *source,

mercurial