mempool.h revision ceace05582699dd86d6b41a20b87b1272b33352b
183bea41fa640dc8117f3eb45ff935cd81377a84Timo Sirainen#ifndef MEMPOOL_H
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MEMPOOL_H
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "macros.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* When DEBUG is enabled, Dovecot warns whenever a memory pool is grown.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen This is done so that the initial pool size could be set large enough so that
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen it wouldn't grow in normal use. For some memory pools it's too difficult
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen to calculate a good initial size, so this prefix should be used with those
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen pools to disable the warning. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MEMPOOL_GROWING "GROWING-"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Memory allocated and reallocated (the new data in it) in pools is always
53dfcefa9440a49d703e49193819a79be99c9ba6Timo Sirainen zeroed, it will cost only a few CPU cycles and may well save some debug
2ef0e8ee48c9683f7bd6698798efa3328e4322d1Timo Sirainen time. */
53dfcefa9440a49d703e49193819a79be99c9ba6Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainentypedef struct pool *pool_t;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct pool_vfuncs {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *(*get_name)(pool_t pool);
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen void (*ref)(pool_t pool);
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen void (*unref)(pool_t *pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void *(*malloc)(pool_t pool, size_t size) ATTR_RETURNS_NONNULL;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void (*free)(pool_t pool, void *mem);
d1e7425048c61d71f41f737ba947687198842dc2Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* memory in old_size..new_size will be zeroed */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void *(*realloc)(pool_t pool, void *mem,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen size_t old_size, size_t new_size)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen /* Frees all the memory in pool. NOTE: system_pool doesn't support
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen this and crashes if it's used */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void (*clear)(pool_t pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Returns the maximum amount of bytes that can be allocated with
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen minimal trouble. If there's no such concept, always returns 0. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen size_t (*get_max_easy_alloc_size)(pool_t pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct pool {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const struct pool_vfuncs *v;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen bool alloconly_pool:1;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen bool datastack_pool:1;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* system_pool uses calloc() + realloc() + free() */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenextern pool_t system_pool;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenextern struct pool static_system_pool;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* memory allocated from data_stack is valid only until next t_pop() call.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen No checks are performed. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenextern pool_t unsafe_data_stack_pool;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Create a new alloc-only pool. Note that `size' specifies the initial
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen malloc()ed block size, part of it is used internally. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenpool_t pool_alloconly_create(const char *name, size_t size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* When allocating memory from returned pool, the data stack frame must be
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen the same as it was when calling this function. pool_unref() also checks
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen that the stack frame is the same. This should make it quite safe to use. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenpool_t pool_datastack_create(void);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Similar to nearest_power(), but try not to exceed buffer's easy
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen allocation size. If you don't have any explicit minimum size, use
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen old_size + 1. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensize_t pool_get_exp_grown_size(pool_t pool, size_t old_size, size_t min_size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define p_new(pool, type, count) \
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ((type *) p_malloc(pool, sizeof(type) * (count)))
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic inline void * ATTR_MALLOC ATTR_RETURNS_NONNULL
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenp_malloc(pool_t pool, size_t size)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return pool->v->malloc(pool, size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic inline void * ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenp_realloc(pool_t pool, void *mem, size_t old_size, size_t new_size)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return pool->v->realloc(pool, mem, old_size, new_size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Free the memory. p_free() and p_free_and_null() are now guaranteed to both
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen set mem=NULL, so either one of them can be used. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define p_free(pool, mem) \
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen STMT_START { \
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen p_free_internal(pool, mem); \
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen (mem) = NULL; \
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen } STMT_END
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define p_free_and_null(pool, mem) p_free(pool, mem)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic inline void p_free_internal(pool_t pool, void *mem)
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen{
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen pool->v->free(pool, mem);
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen}
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainenstatic inline void p_clear(pool_t pool)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen pool->v->clear(pool);
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen}
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainenstatic inline size_t p_get_max_easy_alloc_size(pool_t pool)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return pool->v->get_max_easy_alloc_size(pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic inline const char *pool_get_name(pool_t pool)
2e2a1d720ed53490e8e5c5031e773d395bd5683dTimo Sirainen{
7839797af86d5536124c67f09ede30df08cf678aTimo Sirainen return pool->v->get_name(pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic inline void pool_ref(pool_t pool)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen pool->v->ref(pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic inline void pool_unref(pool_t *pool)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (*pool)->v->unref(pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* These functions are only for pools created with pool_alloconly_create(): */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns how much memory has been allocated from this pool. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensize_t pool_alloconly_get_total_used_size(pool_t pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns how much system memory has been allocated for this pool. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensize_t pool_alloconly_get_total_alloc_size(pool_t pool);
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen/* private: */
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainenvoid pool_system_free(pool_t pool, void *mem);
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen#endif
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen